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 "system/filesys.h"
27 #include "libcli/raw/libcliraw.h"
29 static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
30 const char *fname, BOOL expect_it)
32 TALLOC_CTX *mem_ctx = talloc_init("single_search");
33 union smb_search_data data;
36 time_t c_time, a_time, m_time;
42 status = torture_single_search(cli, mem_ctx,
43 fname, RAW_SEARCH_FULL_DIRECTORY_INFO,
44 FILE_ATTRIBUTE_DIRECTORY,
46 if (!NT_STATUS_IS_OK(status)) {
47 printf("(%s) single_search failed (%s)\n",
48 __location__, nt_errstr(status));
54 union smb_fileinfo io;
55 int nlink = expect_it ? 0 : 1;
57 io.all_info.level = RAW_FILEINFO_ALL_INFO;
58 io.all_info.in.fnum = fnum;
60 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
61 if (!NT_STATUS_IS_OK(status)) {
62 printf("(%s) qpathinfo failed (%s)\n", __location__,
68 if (expect_it != io.all_info.out.delete_pending) {
69 printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
70 expect_it, io.all_info.out.delete_pending);
75 if (nlink != io.all_info.out.nlink) {
76 printf("Expected nlink %d, qfileinfo gave %d\n",
77 nlink, io.all_info.out.nlink);
82 io.standard_info.level = RAW_FILEINFO_STANDARD_INFO;
83 io.standard_info.in.fnum = fnum;
85 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
86 if (!NT_STATUS_IS_OK(status)) {
87 printf("(%s) qpathinfo failed (%s)\n", __location__,
93 if (expect_it != io.standard_info.out.delete_pending) {
94 printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
95 expect_it, io.standard_info.out.delete_pending);
100 if (nlink != io.standard_info.out.nlink) {
101 printf("Expected nlink %d, qfileinfo gave %d\n",
102 nlink, io.all_info.out.nlink);
109 status = smbcli_qpathinfo(cli->tree, fname,
110 &c_time, &a_time, &m_time,
114 if (!NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
115 printf("(%s) qpathinfo did not give correct error "
116 "code (%s) -- NT_STATUS_DELETE_PENDING "
117 "expected\n", __location__,
123 if (!NT_STATUS_IS_OK(status)) {
124 printf("(%s) qpathinfo failed (%s)\n", __location__,
132 talloc_free(mem_ctx);
136 #define CHECK_STATUS(_cli, _expected) do { \
137 if (!NT_STATUS_EQUAL(_cli->tree->session->transport->error.e.nt_status, _expected)) { \
138 printf("(%d) Incorrect status %s - should be %s\n", \
139 __LINE__, nt_errstr(_cli->tree->session->transport->error.e.nt_status), nt_errstr(_expected)); \
145 Test delete on close semantics.
147 BOOL torture_test_delete(void)
149 struct smbcli_state *cli1;
150 struct smbcli_state *cli2 = NULL;
151 const char *fname = "\\delete.file";
152 const char *fname_new = "\\delete.new";
153 const char *dirname = "\\delete.dir";
160 printf("starting delete test\n");
162 if (!torture_open_connection(&cli1)) {
166 if (!torture_open_connection(&cli2)) {
167 printf("(%s) failed to open second connection.\n",
173 smbcli_deltree(cli1->tree, dirname);
175 /* Test 1 - this should delete the file on close. */
177 smbcli_setatr(cli1->tree, fname, 0, 0);
178 smbcli_unlink(cli1->tree, fname);
180 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
182 FILE_ATTRIBUTE_NORMAL,
183 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
184 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
187 printf("(%s) open of %s failed (%s)\n",
188 __location__, fname, smbcli_errstr(cli1->tree));
193 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
194 printf("(%s) close failed (%s)\n",
195 __location__, smbcli_errstr(cli1->tree));
200 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
202 printf("(%s) open of %s succeeded (should fail)\n",
203 __location__, fname);
208 smb_raw_exit(cli1->session);
209 smb_raw_exit(cli2->session);
211 printf("first delete on close test succeeded.\n");
213 /* Test 2 - this should delete the file on close. */
215 smbcli_setatr(cli1->tree, fname, 0, 0);
216 smbcli_unlink(cli1->tree, fname);
218 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
220 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
221 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
224 printf("(%s) open of %s failed (%s)\n",
225 __location__, fname, smbcli_errstr(cli1->tree));
230 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
231 printf("(%s) setting delete_on_close failed (%s)\n",
232 __location__, smbcli_errstr(cli1->tree));
237 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
238 printf("(%s) close failed (%s)\n",
239 __location__, smbcli_errstr(cli1->tree));
244 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
246 printf("(%s) open of %s succeeded should have been deleted on close !\n",
247 __location__, fname);
248 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
249 printf("(%s) close failed (%s)\n",
250 __location__, smbcli_errstr(cli1->tree));
254 smbcli_unlink(cli1->tree, fname);
256 printf("second delete on close test succeeded.\n");
258 smb_raw_exit(cli1->session);
259 smb_raw_exit(cli2->session);
262 smbcli_setatr(cli1->tree, fname, 0, 0);
263 smbcli_unlink(cli1->tree, fname);
265 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
267 FILE_ATTRIBUTE_NORMAL,
268 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
269 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
272 printf("(%s) open - 1 of %s failed (%s)\n",
273 __location__, fname, smbcli_errstr(cli1->tree));
278 /* This should fail with a sharing violation - open for delete is only compatible
279 with SHARE_DELETE. */
281 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
282 SEC_RIGHTS_FILE_READ,
283 FILE_ATTRIBUTE_NORMAL,
284 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
285 NTCREATEX_DISP_OPEN, 0, 0);
288 printf("(%s) open - 2 of %s succeeded - should have failed.\n",
289 __location__, fname);
294 /* This should succeed. */
296 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
297 SEC_RIGHTS_FILE_READ,
298 FILE_ATTRIBUTE_NORMAL,
299 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
300 NTCREATEX_DISP_OPEN, 0, 0);
303 printf("(%s) open - 2 of %s failed (%s)\n",
304 __location__, fname, smbcli_errstr(cli1->tree));
309 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
310 printf("(%s) setting delete_on_close failed (%s)\n",
311 __location__, smbcli_errstr(cli1->tree));
316 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
317 printf("(%s) close 1 failed (%s)\n",
318 __location__, smbcli_errstr(cli1->tree));
323 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
324 printf("(%s) close 2 failed (%s)\n",
325 __location__, smbcli_errstr(cli1->tree));
330 /* This should fail - file should no longer be there. */
332 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
334 printf("(%s) open of %s succeeded should have been deleted on close !\n",
335 __location__, fname);
336 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
337 printf("(%s) close failed (%s)\n",
338 __location__, smbcli_errstr(cli1->tree));
340 smbcli_unlink(cli1->tree, fname);
344 printf("third delete on close test succeeded.\n");
346 smb_raw_exit(cli1->session);
347 smb_raw_exit(cli2->session);
350 smbcli_setatr(cli1->tree, fname, 0, 0);
351 status = smbcli_unlink(cli1->tree, fname);
352 if (NT_STATUS_IS_OK(status)) {
353 printf("(%s) succeeded unlink of %s\n", __location__, fname);
358 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
360 SEC_FILE_WRITE_DATA |
362 FILE_ATTRIBUTE_NORMAL,
363 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
364 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
367 printf("(%s) open of %s failed (%s)\n",
368 __location__, fname, smbcli_errstr(cli1->tree));
373 /* This should succeed. */
374 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
375 SEC_RIGHTS_FILE_READ,
376 FILE_ATTRIBUTE_NORMAL,
377 NTCREATEX_SHARE_ACCESS_READ |
378 NTCREATEX_SHARE_ACCESS_WRITE |
379 NTCREATEX_SHARE_ACCESS_DELETE,
380 NTCREATEX_DISP_OPEN, 0, 0);
382 printf("(%s) open - 2 of %s failed (%s)\n",
383 __location__, fname, smbcli_errstr(cli1->tree));
388 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
389 printf("(%s) close - 1 failed (%s)\n",
390 __location__, smbcli_errstr(cli1->tree));
395 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
396 printf("(%s) setting delete_on_close failed (%s)\n",
397 __location__, smbcli_errstr(cli1->tree));
402 /* This should fail - no more opens once delete on close set. */
403 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
404 SEC_RIGHTS_FILE_READ,
405 FILE_ATTRIBUTE_NORMAL,
406 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
407 NTCREATEX_DISP_OPEN, 0, 0);
409 printf("(%s) open - 3 of %s succeeded ! Should have failed.\n",
410 __location__, fname );
414 CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
416 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
417 printf("(%s) close - 2 failed (%s)\n",
418 __location__, smbcli_errstr(cli1->tree));
423 smb_raw_exit(cli1->session);
424 smb_raw_exit(cli2->session);
426 printf("fourth delete on close test succeeded.\n");
429 smbcli_setatr(cli1->tree, fname, 0, 0);
430 smbcli_unlink(cli1->tree, fname);
432 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
434 printf("(%s) open of %s failed (%s)\n",
435 __location__, fname, smbcli_errstr(cli1->tree));
440 /* This should fail - only allowed on NT opens with DELETE access. */
442 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
443 printf("(%s) setting delete_on_close on OpenX file succeeded - should fail !\n",
449 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
450 printf("(%s) close - 2 failed (%s)\n",
451 __location__, smbcli_errstr(cli1->tree));
456 smb_raw_exit(cli1->session);
457 smb_raw_exit(cli2->session);
459 printf("fifth delete on close test succeeded.\n");
462 smbcli_setatr(cli1->tree, fname, 0, 0);
463 smbcli_unlink(cli1->tree, fname);
465 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
466 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
467 FILE_ATTRIBUTE_NORMAL,
468 NTCREATEX_SHARE_ACCESS_READ |
469 NTCREATEX_SHARE_ACCESS_WRITE |
470 NTCREATEX_SHARE_ACCESS_DELETE,
471 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
474 printf("(%s) open of %s failed (%s)\n",
475 __location__, fname, smbcli_errstr(cli1->tree));
480 /* This should fail - only allowed on NT opens with DELETE access. */
482 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
483 printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
489 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
490 printf("(%s) close - 2 failed (%s)\n",
491 __location__, smbcli_errstr(cli1->tree));
496 smb_raw_exit(cli1->session);
497 smb_raw_exit(cli2->session);
499 printf("sixth delete on close test succeeded.\n");
502 smbcli_setatr(cli1->tree, fname, 0, 0);
503 smbcli_unlink(cli1->tree, fname);
505 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
507 SEC_FILE_WRITE_DATA |
509 FILE_ATTRIBUTE_NORMAL, 0,
510 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
513 printf("(%s) open of %s failed (%s)\n",
514 __location__, fname, smbcli_errstr(cli1->tree));
519 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
520 printf("(%s) setting delete_on_close on file failed !\n",
526 correct &= check_delete_on_close(cli1, fnum1, fname, True);
528 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
529 printf("(%s) unsetting delete_on_close on file failed !\n",
535 correct &= check_delete_on_close(cli1, fnum1, fname, False);
537 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
538 printf("(%s) close - 2 failed (%s)\n",
539 __location__, smbcli_errstr(cli1->tree));
544 /* This next open should succeed - we reset the flag. */
546 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
548 printf("(%s) open of %s failed (%s)\n",
549 __location__, fname, smbcli_errstr(cli1->tree));
554 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
555 printf("(%s) close - 2 failed (%s)\n",
556 __location__, smbcli_errstr(cli1->tree));
561 smb_raw_exit(cli1->session);
562 smb_raw_exit(cli2->session);
564 printf("seventh delete on close test succeeded.\n");
567 smbcli_setatr(cli1->tree, fname, 0, 0);
568 smbcli_unlink(cli1->tree, fname);
570 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
574 FILE_ATTRIBUTE_NORMAL,
575 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
576 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
579 printf("(%s) open of %s failed (%s)\n",
580 __location__, fname, smbcli_errstr(cli1->tree));
585 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
589 FILE_ATTRIBUTE_NORMAL,
590 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
591 NTCREATEX_DISP_OPEN, 0, 0);
594 printf("(%s) open of %s failed (%s)\n",
595 __location__, fname, smbcli_errstr(cli1->tree));
600 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
601 printf("(%s) setting delete_on_close on file failed !\n",
607 correct &= check_delete_on_close(cli1, fnum1, fname, True);
608 correct &= check_delete_on_close(cli2, fnum2, fname, True);
610 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
611 printf("(%s) close - 1 failed (%s)\n",
612 __location__, smbcli_errstr(cli1->tree));
617 correct &= check_delete_on_close(cli1, -1, fname, True);
618 correct &= check_delete_on_close(cli2, fnum2, fname, True);
620 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
621 printf("(%s) close - 2 failed (%s)\n",
622 __location__, smbcli_errstr(cli2->tree));
627 /* This should fail.. */
628 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
630 printf("(%s) open of %s succeeded should have been deleted on close !\n",
631 __location__, fname);
635 printf("eighth delete on close test succeeded.\n");
637 smb_raw_exit(cli1->session);
638 smb_raw_exit(cli2->session);
640 /* This should fail - we need to set DELETE_ACCESS. */
641 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
642 SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
643 FILE_ATTRIBUTE_NORMAL,
644 NTCREATEX_SHARE_ACCESS_NONE,
645 NTCREATEX_DISP_OVERWRITE_IF,
646 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
649 printf("(%s) open of %s succeeded should have failed!\n",
650 __location__, fname);
655 smb_raw_exit(cli1->session);
656 smb_raw_exit(cli2->session);
658 printf("ninth delete on close test succeeded.\n");
660 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
664 FILE_ATTRIBUTE_NORMAL,
665 NTCREATEX_SHARE_ACCESS_NONE,
666 NTCREATEX_DISP_OVERWRITE_IF,
667 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
669 printf("(%s) open of %s failed (%s)\n",
670 __location__, fname, smbcli_errstr(cli1->tree));
675 /* This should delete the file. */
676 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
677 printf("(%s) close failed (%s)\n",
678 __location__, smbcli_errstr(cli1->tree));
683 /* This should fail.. */
684 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
686 printf("(%s) open of %s succeeded should have been deleted on close !\n",
687 __location__, fname);
691 printf("tenth delete on close test succeeded.\n");
693 smb_raw_exit(cli1->session);
694 smb_raw_exit(cli2->session);
696 /* test 11 - does having read only attribute still allow delete on close. */
698 smbcli_setatr(cli1->tree, fname, 0, 0);
699 smbcli_unlink(cli1->tree, fname);
701 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
703 FILE_ATTRIBUTE_READONLY,
704 NTCREATEX_SHARE_ACCESS_NONE,
705 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
708 printf("(%s) open of %s failed (%s)\n",
709 __location__, fname, smbcli_errstr(cli1->tree));
714 status = smbcli_nt_delete_on_close(cli1->tree, fnum1, True);
716 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
717 printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n",
718 __location__, smbcli_errstr(cli1->tree));
723 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
724 printf("(%s) close failed (%s)\n",
725 __location__, smbcli_errstr(cli1->tree));
730 smbcli_setatr(cli1->tree, fname, 0, 0);
731 smbcli_unlink(cli1->tree, fname);
733 smb_raw_exit(cli1->session);
734 smb_raw_exit(cli2->session);
736 printf("eleventh delete on close test succeeded.\n");
738 /* test 12 - does having read only attribute still allow delete on
739 * close at time of open. */
741 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
743 FILE_ATTRIBUTE_READONLY,
744 NTCREATEX_SHARE_ACCESS_DELETE,
745 NTCREATEX_DISP_OVERWRITE_IF,
746 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
749 printf("(%s) open of %s succeeded. Should fail with "
750 "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
751 smbcli_close(cli1->tree, fnum1);
755 status = smbcli_nt_error(cli1->tree);
756 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
757 printf("(%s) setting delete_on_close on open should "
758 "fail with NT_STATUS_CANNOT_DELETE. Got %s "
760 __location__, smbcli_errstr(cli1->tree));
766 smb_raw_exit(cli1->session);
767 smb_raw_exit(cli2->session);
769 printf("twelvth delete on close test succeeded.\n");
771 /* Test 13: Does resetting the delete on close flag affect a second
774 smbcli_setatr(cli1->tree, fname, 0, 0);
775 smbcli_unlink(cli1->tree, fname);
777 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
781 FILE_ATTRIBUTE_NORMAL,
782 NTCREATEX_SHARE_ACCESS_READ|
783 NTCREATEX_SHARE_ACCESS_WRITE|
784 NTCREATEX_SHARE_ACCESS_DELETE,
785 NTCREATEX_DISP_OVERWRITE_IF,
789 printf("(%s) open of %s failed (%s)\n",
790 __location__, fname, smbcli_errstr(cli1->tree));
795 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
799 FILE_ATTRIBUTE_NORMAL,
800 NTCREATEX_SHARE_ACCESS_READ|
801 NTCREATEX_SHARE_ACCESS_WRITE|
802 NTCREATEX_SHARE_ACCESS_DELETE,
803 NTCREATEX_DISP_OPEN, 0, 0);
806 printf("(%s) open of %s failed (%s)\n",
807 __location__, fname, smbcli_errstr(cli2->tree));
812 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1,
814 printf("(%s) setting delete_on_close on file failed !\n",
820 correct &= check_delete_on_close(cli1, fnum1, fname, True);
821 correct &= check_delete_on_close(cli2, fnum2, fname, True);
823 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli2->tree, fnum2,
825 printf("(%s) setting delete_on_close on file failed !\n",
831 correct &= check_delete_on_close(cli1, fnum1, fname, False);
832 correct &= check_delete_on_close(cli2, fnum2, fname, False);
834 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
835 printf("(%s) close - 1 failed (%s)\n",
836 __location__, smbcli_errstr(cli1->tree));
841 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
842 printf("(%s) close - 2 failed (%s)\n",
843 __location__, smbcli_errstr(cli2->tree));
848 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
851 printf("(%s) open of %s failed!\n",
852 __location__, fname);
857 smbcli_close(cli1->tree, fnum1);
858 smbcli_unlink(cli1->tree, fname);
860 smb_raw_exit(cli1->session);
861 smb_raw_exit(cli2->session);
863 printf("thirteenth delete on close test succeeded.\n");
865 /* Test 14 -- directory */
867 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
871 FILE_ATTRIBUTE_DIRECTORY,
872 NTCREATEX_SHARE_ACCESS_READ|
873 NTCREATEX_SHARE_ACCESS_WRITE|
874 NTCREATEX_SHARE_ACCESS_DELETE,
875 NTCREATEX_DISP_CREATE, 0, 0);
877 printf("(%s) open of %s failed: %s!\n",
878 __location__, dirname, smbcli_errstr(cli1->tree));
883 check_delete_on_close(cli1, dnum1, dirname, False);
884 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, dnum1, True))) {
885 printf("(%s) setting delete_on_close on file failed !\n",
890 check_delete_on_close(cli1, dnum1, dirname, True);
891 smbcli_close(cli1->tree, dnum1);
893 /* Now it should be gone... */
895 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
899 FILE_ATTRIBUTE_DIRECTORY,
900 NTCREATEX_SHARE_ACCESS_READ|
901 NTCREATEX_SHARE_ACCESS_WRITE|
902 NTCREATEX_SHARE_ACCESS_DELETE,
903 NTCREATEX_DISP_OPEN, 0, 0);
905 printf("(%s) setting delete_on_close on file succeeded !\n",
911 smb_raw_exit(cli1->session);
912 smb_raw_exit(cli2->session);
914 printf("fourteenth delete on close test succeeded.\n");
916 /* Test 15: delete on close under rename */
918 smbcli_setatr(cli1->tree, fname, 0, 0);
919 smbcli_unlink(cli1->tree, fname);
920 smbcli_unlink(cli1->tree, fname_new);
922 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
924 FILE_ATTRIBUTE_NORMAL,
925 NTCREATEX_SHARE_ACCESS_READ|
926 NTCREATEX_SHARE_ACCESS_WRITE|
927 NTCREATEX_SHARE_ACCESS_DELETE,
928 NTCREATEX_DISP_OVERWRITE_IF,
932 printf("(%s) open - 1 of %s failed (%s)\n",
933 __location__, fname, smbcli_errstr(cli1->tree));
938 status = smbcli_rename(cli2->tree, fname, fname_new);
940 if (!NT_STATUS_IS_OK(status)) {
941 printf("(%s) renaming failed: %s !\n",
942 __location__, nt_errstr(status));
947 fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0,
949 FILE_ATTRIBUTE_NORMAL,
950 NTCREATEX_SHARE_ACCESS_READ|
951 NTCREATEX_SHARE_ACCESS_WRITE|
952 NTCREATEX_SHARE_ACCESS_DELETE,
953 NTCREATEX_DISP_OVERWRITE_IF,
957 printf("(%s) open - 1 of %s failed (%s)\n",
958 __location__, fname_new, smbcli_errstr(cli1->tree));
963 status = smbcli_nt_delete_on_close(cli2->tree, fnum2, True);
965 if (!NT_STATUS_IS_OK(status)) {
966 printf("(%s) setting delete_on_close on file failed !\n",
972 smbcli_close(cli2->tree, fnum2);
974 /* The file should be around under the new name, there's a second
977 if (!check_delete_on_close(cli1, fnum1, fname_new, True)) {
978 printf("(%s) checking delete on close on file %s failed!\n",
979 __location__, fname_new);
984 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
986 FILE_ATTRIBUTE_NORMAL,
987 NTCREATEX_SHARE_ACCESS_READ|
988 NTCREATEX_SHARE_ACCESS_WRITE|
989 NTCREATEX_SHARE_ACCESS_DELETE,
990 NTCREATEX_DISP_OVERWRITE_IF,
994 printf("(%s) open - 1 of %s failed (%s)\n",
995 __location__, fname, smbcli_errstr(cli1->tree));
1000 smbcli_close(cli2->tree, fnum2);
1001 smbcli_close(cli1->tree, fnum1);
1003 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1005 FILE_ATTRIBUTE_NORMAL,
1006 NTCREATEX_SHARE_ACCESS_READ|
1007 NTCREATEX_SHARE_ACCESS_WRITE|
1008 NTCREATEX_SHARE_ACCESS_DELETE,
1009 NTCREATEX_DISP_OPEN,
1013 printf("(%s) open - 1 of %s failed (%s)\n",
1014 __location__, fname, smbcli_errstr(cli1->tree));
1019 smbcli_close(cli1->tree, fnum1);
1021 fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0,
1023 FILE_ATTRIBUTE_NORMAL,
1024 NTCREATEX_SHARE_ACCESS_READ|
1025 NTCREATEX_SHARE_ACCESS_WRITE|
1026 NTCREATEX_SHARE_ACCESS_DELETE,
1027 NTCREATEX_DISP_OPEN,
1031 printf("(%s) smbcli_open succeeded, should have "
1032 "failed\n", __location__);
1033 smbcli_close(cli1->tree, fnum1);
1038 smb_raw_exit(cli1->session);
1039 smb_raw_exit(cli2->session);
1041 printf("fifteenth delete on close test succeeded.\n");
1045 /* Ensure the file doesn't already exist. */
1046 smbcli_close(cli1->tree, fnum1);
1047 smbcli_close(cli1->tree, fnum2);
1048 smbcli_setatr(cli1->tree, fname, 0, 0);
1049 smbcli_unlink(cli1->tree, fname);
1051 /* Firstly create with all access, but delete on close. */
1052 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1053 SEC_RIGHTS_FILE_ALL,
1054 FILE_ATTRIBUTE_NORMAL,
1055 NTCREATEX_SHARE_ACCESS_READ|
1056 NTCREATEX_SHARE_ACCESS_WRITE|
1057 NTCREATEX_SHARE_ACCESS_DELETE,
1058 NTCREATEX_DISP_CREATE,
1059 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1062 printf("(%s) open - 1 of %s failed (%s)\n",
1063 __location__, fname, smbcli_errstr(cli1->tree));
1068 /* The delete on close bit is *not* reported as being set. */
1069 check_delete_on_close(cli1, fnum1, fname, False);
1071 /* Now try opening again for read-only. */
1072 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1073 SEC_RIGHTS_FILE_READ,
1074 FILE_ATTRIBUTE_NORMAL,
1075 NTCREATEX_SHARE_ACCESS_READ|
1076 NTCREATEX_SHARE_ACCESS_WRITE|
1077 NTCREATEX_SHARE_ACCESS_DELETE,
1078 NTCREATEX_DISP_OPEN,
1084 printf("(%s) open - 1 of %s failed (%s)\n",
1085 __location__, fname, smbcli_errstr(cli1->tree));
1090 /* Now close both.... */
1091 smbcli_close(cli1->tree, fnum1);
1092 smbcli_close(cli1->tree, fnum2);
1094 /* And the file should be deleted ! */
1095 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1097 printf("(%s) open of %s succeeded (should fail)\n",
1098 __location__, fname);
1103 smb_raw_exit(cli1->session);
1104 smb_raw_exit(cli2->session);
1106 printf("sixteenth delete on close test succeeded.\n");
1110 /* Ensure the file doesn't already exist. */
1111 smbcli_close(cli1->tree, fnum1);
1112 smbcli_close(cli1->tree, fnum2);
1113 smbcli_setatr(cli1->tree, fname, 0, 0);
1114 smbcli_unlink(cli1->tree, fname);
1116 /* Firstly open and create with all access */
1117 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1118 SEC_RIGHTS_FILE_ALL,
1119 FILE_ATTRIBUTE_NORMAL,
1120 NTCREATEX_SHARE_ACCESS_READ|
1121 NTCREATEX_SHARE_ACCESS_WRITE|
1122 NTCREATEX_SHARE_ACCESS_DELETE,
1123 NTCREATEX_DISP_CREATE,
1126 printf("(%s) open - 1 of %s failed (%s)\n",
1127 __location__, fname, smbcli_errstr(cli1->tree));
1132 /* And close - just to create the file. */
1133 smbcli_close(cli1->tree, fnum1);
1135 /* Next open with all access, but add delete on close. */
1136 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1137 SEC_RIGHTS_FILE_ALL,
1138 FILE_ATTRIBUTE_NORMAL,
1139 NTCREATEX_SHARE_ACCESS_READ|
1140 NTCREATEX_SHARE_ACCESS_WRITE|
1141 NTCREATEX_SHARE_ACCESS_DELETE,
1142 NTCREATEX_DISP_OPEN,
1143 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1146 printf("(%s) open - 1 of %s failed (%s)\n",
1147 __location__, fname, smbcli_errstr(cli1->tree));
1152 /* The delete on close bit is *not* reported as being set. */
1153 check_delete_on_close(cli1, fnum1, fname, False);
1155 /* Now try opening again for read-only. */
1156 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1157 SEC_RIGHTS_FILE_READ,
1158 FILE_ATTRIBUTE_NORMAL,
1159 NTCREATEX_SHARE_ACCESS_READ|
1160 NTCREATEX_SHARE_ACCESS_WRITE|
1161 NTCREATEX_SHARE_ACCESS_DELETE,
1162 NTCREATEX_DISP_OPEN,
1167 printf("(%s) open - 1 of %s failed (%s)\n",
1168 __location__, fname, smbcli_errstr(cli1->tree));
1173 /* Now close both.... */
1174 smbcli_close(cli1->tree, fnum1);
1175 smbcli_close(cli1->tree, fnum2);
1177 /* See if the file is deleted - shouldn't be.... */
1178 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1180 printf("(%s) open of %s failed (should succeed) - %s\n",
1181 __location__, fname, smbcli_errstr(cli1->tree));
1186 smb_raw_exit(cli1->session);
1187 smb_raw_exit(cli2->session);
1189 printf("seventeenth delete on close test succeeded.\n");
1191 /* Test 18. With directories. */
1193 /* Ensure the file doesn't already exist. */
1194 smbcli_close(cli1->tree, fnum1);
1195 smbcli_close(cli1->tree, fnum2);
1197 smbcli_deltree(cli1->tree, dirname);
1199 /* Firstly create with all access, but delete on close. */
1200 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1202 SEC_FILE_WRITE_DATA|
1204 FILE_ATTRIBUTE_DIRECTORY,
1205 NTCREATEX_SHARE_ACCESS_READ|
1206 NTCREATEX_SHARE_ACCESS_WRITE|
1207 NTCREATEX_SHARE_ACCESS_DELETE,
1208 NTCREATEX_DISP_CREATE,
1209 NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1212 printf("(%s) open - 1 of %s failed (%s)\n",
1213 __location__, dirname, smbcli_errstr(cli1->tree));
1218 /* The delete on close bit is *not* reported as being set. */
1219 check_delete_on_close(cli1, fnum1, dirname, False);
1221 /* Now try opening again for read-only. */
1222 fnum2 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1223 SEC_RIGHTS_FILE_READ,
1224 FILE_ATTRIBUTE_DIRECTORY,
1225 NTCREATEX_SHARE_ACCESS_READ|
1226 NTCREATEX_SHARE_ACCESS_WRITE|
1227 NTCREATEX_SHARE_ACCESS_DELETE,
1228 NTCREATEX_DISP_OPEN,
1229 NTCREATEX_OPTIONS_DIRECTORY, 0);
1234 printf("(%s) open - 1 of %s failed (%s)\n",
1235 __location__, dirname, smbcli_errstr(cli1->tree));
1240 /* Now close both.... */
1241 smbcli_close(cli1->tree, fnum1);
1242 smbcli_close(cli1->tree, fnum2);
1244 /* And the directory should be deleted ! */
1245 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1246 SEC_RIGHTS_FILE_READ,
1247 FILE_ATTRIBUTE_DIRECTORY,
1248 NTCREATEX_SHARE_ACCESS_READ|
1249 NTCREATEX_SHARE_ACCESS_WRITE|
1250 NTCREATEX_SHARE_ACCESS_DELETE,
1251 NTCREATEX_DISP_OPEN,
1252 NTCREATEX_OPTIONS_DIRECTORY, 0);
1254 printf("(%s) open of %s succeeded (should fail)\n",
1255 __location__, dirname);
1260 smb_raw_exit(cli1->session);
1261 smb_raw_exit(cli2->session);
1263 printf("eighteenth delete on close test succeeded.\n");
1267 smbcli_deltree(cli1->tree, dirname);
1269 /* Firstly open and create with all access */
1270 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1272 SEC_FILE_WRITE_DATA|
1274 FILE_ATTRIBUTE_DIRECTORY,
1275 NTCREATEX_SHARE_ACCESS_READ|
1276 NTCREATEX_SHARE_ACCESS_WRITE|
1277 NTCREATEX_SHARE_ACCESS_DELETE,
1278 NTCREATEX_DISP_CREATE,
1279 NTCREATEX_OPTIONS_DIRECTORY, 0);
1282 printf("(%s) open - 1 of %s failed (%s)\n",
1283 __location__, dirname, smbcli_errstr(cli1->tree));
1288 /* And close - just to create the directory. */
1289 smbcli_close(cli1->tree, fnum1);
1291 /* Next open with all access, but add delete on close. */
1292 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1294 SEC_FILE_WRITE_DATA|
1296 FILE_ATTRIBUTE_DIRECTORY,
1297 NTCREATEX_SHARE_ACCESS_READ|
1298 NTCREATEX_SHARE_ACCESS_WRITE|
1299 NTCREATEX_SHARE_ACCESS_DELETE,
1300 NTCREATEX_DISP_OPEN,
1301 NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1304 printf("(%s) open - 1 of %s failed (%s)\n",
1305 __location__, fname, smbcli_errstr(cli1->tree));
1310 /* The delete on close bit is *not* reported as being set. */
1311 check_delete_on_close(cli1, fnum1, dirname, False);
1313 /* Now try opening again for read-only. */
1314 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1315 SEC_RIGHTS_FILE_READ,
1316 FILE_ATTRIBUTE_DIRECTORY,
1317 NTCREATEX_SHARE_ACCESS_READ|
1318 NTCREATEX_SHARE_ACCESS_WRITE|
1319 NTCREATEX_SHARE_ACCESS_DELETE,
1320 NTCREATEX_DISP_OPEN,
1321 NTCREATEX_OPTIONS_DIRECTORY, 0);
1325 printf("(%s) open - 1 of %s failed (%s)\n",
1326 __location__, dirname, smbcli_errstr(cli1->tree));
1331 /* Now close both.... */
1332 smbcli_close(cli1->tree, fnum1);
1333 smbcli_close(cli1->tree, fnum2);
1335 /* See if the file is deleted - shouldn't be.... */
1336 fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1337 SEC_RIGHTS_FILE_READ,
1338 FILE_ATTRIBUTE_DIRECTORY,
1339 NTCREATEX_SHARE_ACCESS_READ|
1340 NTCREATEX_SHARE_ACCESS_WRITE|
1341 NTCREATEX_SHARE_ACCESS_DELETE,
1342 NTCREATEX_DISP_OPEN,
1343 NTCREATEX_OPTIONS_DIRECTORY, 0);
1345 printf("(%s) open of %s failed (should succeed)\n",
1346 __location__, dirname);
1351 smb_raw_exit(cli1->session);
1352 smb_raw_exit(cli2->session);
1354 printf("nineteenth delete on close test succeeded.\n");
1356 /* Test 20 -- non-empty directory hardest to get right... */
1358 smbcli_deltree(cli1->tree, dirname);
1360 dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1362 SEC_FILE_WRITE_DATA|
1364 FILE_ATTRIBUTE_DIRECTORY,
1365 NTCREATEX_SHARE_ACCESS_READ|
1366 NTCREATEX_SHARE_ACCESS_WRITE|
1367 NTCREATEX_SHARE_ACCESS_DELETE,
1368 NTCREATEX_DISP_CREATE,
1369 NTCREATEX_OPTIONS_DIRECTORY, 0);
1371 printf("(%s) open of %s failed: %s!\n",
1372 __location__, dirname, smbcli_errstr(cli1->tree));
1377 check_delete_on_close(cli1, dnum1, dirname, False);
1378 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1382 asprintf(&fullname, "\\%s%s", dirname, fname);
1383 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1386 printf("(%s) smbcli_open succeeded, should have "
1388 __location__, smbcli_errstr(cli1->tree));
1393 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree),
1394 NT_STATUS_DELETE_PENDING)) {
1395 printf("(%s) smbcli_open returned %s, expected "
1396 "NT_STATUS_DELETE_PENDING\n",
1397 __location__, smbcli_errstr(cli1->tree));
1403 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, False);
1404 if (!NT_STATUS_IS_OK(status)) {
1405 printf("(%s) setting delete_on_close on file failed !\n",
1413 asprintf(&fullname, "\\%s%s", dirname, fname);
1414 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1417 printf("(%s) smbcli_open failed: %s\n",
1418 __location__, smbcli_errstr(cli1->tree));
1422 smbcli_close(cli1->tree, fnum1);
1425 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1427 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1428 printf("(%s) setting delete_on_close returned %s, expected "
1429 "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__,
1430 smbcli_errstr(cli1->tree));
1435 smbcli_close(cli1->tree, dnum1);
1437 smb_raw_exit(cli1->session);
1438 smb_raw_exit(cli2->session);
1440 printf("twentieth delete on close test succeeded.\n");
1442 printf("finished delete test\n");
1445 /* FIXME: This will crash if we aborted before cli2 got
1446 * intialized, because these functions don't handle
1447 * uninitialized connections. */
1449 smbcli_close(cli1->tree, fnum1);
1450 smbcli_close(cli1->tree, fnum2);
1451 smbcli_setatr(cli1->tree, fname, 0, 0);
1452 smbcli_unlink(cli1->tree, fname);
1454 smbcli_deltree(cli1->tree, dirname);
1456 if (!torture_close_connection(cli1)) {
1459 if (!torture_close_connection(cli2)) {