r16182: Better test the 15 out of 20 tests we right now survive than not test at
[Samba.git] / source / torture / basic / delete.c
blobc7b7fffa18acc1ce024fe1cdffa94d3dabe93796
1 /*
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.
23 #include "includes.h"
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,
34 const char *where)
36 TALLOC_CTX *mem_ctx = talloc_init("single_search");
37 union smb_search_data data;
38 NTSTATUS status;
40 time_t c_time, a_time, m_time;
41 size_t size;
42 uint16_t mode;
44 BOOL res = True;
46 status = torture_single_search(cli, mem_ctx,
47 fname, RAW_SEARCH_FULL_DIRECTORY_INFO,
48 FILE_ATTRIBUTE_DIRECTORY,
49 &data);
50 if (!NT_STATUS_IS_OK(status)) {
51 printf("(%s) single_search failed (%s)\n",
52 where, nt_errstr(status));
53 res = False;
54 goto done;
57 if (fnum != -1) {
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,
67 nt_errstr(status));
68 res = False;
69 goto done;
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);
75 res = False;
76 goto done;
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);
82 res = False;
83 goto done;
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,
92 nt_errstr(status));
93 res = False;
94 goto done;
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);
100 res = False;
101 goto done;
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);
107 res = False;
108 goto done;
113 status = smbcli_qpathinfo(cli->tree, fname,
114 &c_time, &a_time, &m_time,
115 &size, &mode);
117 if (expect_it) {
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 "
121 "expected\n", where,
122 nt_errstr(status));
123 res = False;
124 goto done;
126 } else {
127 if (!NT_STATUS_IS_OK(status)) {
128 printf("(%s) qpathinfo failed (%s)\n", where,
129 nt_errstr(status));
130 res = False;
131 goto done;
135 done:
136 talloc_free(mem_ctx);
137 return res;
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)); \
144 correct = False; \
145 goto fail; \
146 }} while (0)
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)
168 int fnum1 = -1;
170 del_clean_area(cli1, cli2);
172 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
173 SEC_RIGHTS_FILE_ALL,
174 FILE_ATTRIBUTE_NORMAL,
175 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
176 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
178 if (fnum1 == -1) {
179 printf("(%s) open of %s failed (%s)\n",
180 __location__, fname, smbcli_errstr(cli1->tree));
181 return False;
184 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
185 printf("(%s) close failed (%s)\n",
186 __location__, smbcli_errstr(cli1->tree));
187 return False;
190 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
191 if (fnum1 != -1) {
192 printf("(%s) open of %s succeeded (should fail)\n",
193 __location__, fname);
194 return False;
197 printf("first delete on close test succeeded.\n");
198 return True;
201 /* Test 2 - this should delete the file on close. */
202 static BOOL deltest2(struct smbcli_state *cli1, struct smbcli_state *cli2)
204 int fnum1 = -1;
206 del_clean_area(cli1, cli2);
208 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
209 SEC_RIGHTS_FILE_ALL,
210 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
211 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
213 if (fnum1 == -1) {
214 printf("(%s) open of %s failed (%s)\n",
215 __location__, fname, smbcli_errstr(cli1->tree));
216 return False;
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));
222 return False;
225 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
226 printf("(%s) close failed (%s)\n",
227 __location__, smbcli_errstr(cli1->tree));
228 return False;
231 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
232 if (fnum1 != -1) {
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));
238 return False;
240 smbcli_unlink(cli1->tree, fname);
241 } else {
242 printf("second delete on close test succeeded.\n");
244 return True;
247 /* Test 3 - ... */
248 static BOOL deltest3(struct smbcli_state *cli1, struct smbcli_state *cli2)
250 int fnum1 = -1;
251 int fnum2 = -1;
253 del_clean_area(cli1, cli2);
255 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
256 SEC_RIGHTS_FILE_ALL,
257 FILE_ATTRIBUTE_NORMAL,
258 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
259 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
261 if (fnum1 == -1) {
262 printf("(%s) open - 1 of %s failed (%s)\n",
263 __location__, fname, smbcli_errstr(cli1->tree));
264 return False;
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);
276 if (fnum2 != -1) {
277 printf("(%s) open - 2 of %s succeeded - should have failed.\n",
278 __location__, fname);
279 return False;
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);
290 if (fnum2 == -1) {
291 printf("(%s) open - 2 of %s failed (%s)\n",
292 __location__, fname, smbcli_errstr(cli1->tree));
293 return False;
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));
299 return False;
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));
305 return False;
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));
311 return False;
314 /* This should fail - file should no longer be there. */
316 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
317 if (fnum1 != -1) {
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);
325 return False;
326 } else {
327 printf("third delete on close test succeeded.\n");
329 return True;
332 /* Test 4 ... */
333 static BOOL deltest4(struct smbcli_state *cli1, struct smbcli_state *cli2)
335 int fnum1 = -1;
336 int fnum2 = -1;
337 BOOL correct = True;
339 del_clean_area(cli1, cli2);
341 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
342 SEC_FILE_READ_DATA |
343 SEC_FILE_WRITE_DATA |
344 SEC_STD_DELETE,
345 FILE_ATTRIBUTE_NORMAL,
346 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
347 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
349 if (fnum1 == -1) {
350 printf("(%s) open of %s failed (%s)\n",
351 __location__, fname, smbcli_errstr(cli1->tree));
352 return False;
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);
363 if (fnum2 == -1) {
364 printf("(%s) open - 2 of %s failed (%s)\n",
365 __location__, fname, smbcli_errstr(cli1->tree));
366 return False;
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));
372 return False;
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));
378 return False;
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);
387 if (fnum2 != -1) {
388 printf("(%s) open - 3 of %s succeeded ! Should have failed.\n",
389 __location__, fname );
390 return False;
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));
397 return False;
400 printf("fourth delete on close test succeeded.\n");
402 fail:
404 return correct;
407 /* Test 5 ... */
408 static BOOL deltest5(struct smbcli_state *cli1, struct smbcli_state *cli2)
410 int fnum1 = -1;
412 del_clean_area(cli1, cli2);
414 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
415 if (fnum1 == -1) {
416 printf("(%s) open of %s failed (%s)\n",
417 __location__, fname, smbcli_errstr(cli1->tree));
418 return False;
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",
425 __location__);
426 return False;
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));
432 return False;
435 printf("fifth delete on close test succeeded.\n");
436 return True;
439 /* Test 6 ... */
440 static BOOL deltest6(struct smbcli_state *cli1, struct smbcli_state *cli2)
442 int fnum1 = -1;
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);
454 if (fnum1 == -1) {
455 printf("(%s) open of %s failed (%s)\n",
456 __location__, fname, smbcli_errstr(cli1->tree));
457 return False;
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",
464 __location__);
465 return False;
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));
471 return False;
474 printf("sixth delete on close test succeeded.\n");
475 return True;
478 /* Test 7 ... */
479 static BOOL deltest7(struct smbcli_state *cli1, struct smbcli_state *cli2)
481 int fnum1 = -1;
482 BOOL correct = True;
484 del_clean_area(cli1, cli2);
486 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
487 SEC_FILE_READ_DATA |
488 SEC_FILE_WRITE_DATA |
489 SEC_STD_DELETE,
490 FILE_ATTRIBUTE_NORMAL, 0,
491 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
493 if (fnum1 == -1) {
494 printf("(%s) open of %s failed (%s)\n",
495 __location__, fname, smbcli_errstr(cli1->tree));
496 correct = False;
497 goto fail;
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",
502 __location__);
503 correct = False;
504 goto fail;
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",
511 __location__);
512 correct = False;
513 goto fail;
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));
521 correct = False;
522 goto fail;
525 /* This next open should succeed - we reset the flag. */
527 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
528 if (fnum1 == -1) {
529 printf("(%s) open of %s failed (%s)\n",
530 __location__, fname, smbcli_errstr(cli1->tree));
531 correct = False;
532 goto fail;
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));
538 correct = False;
539 goto fail;
542 printf("seventh delete on close test succeeded.\n");
544 fail:
546 return correct;
549 /* Test 8 ... */
550 static BOOL deltest8(struct smbcli_state *cli1, struct smbcli_state *cli2)
552 int fnum1 = -1;
553 int fnum2 = -1;
554 BOOL correct = True;
556 del_clean_area(cli1, cli2);
558 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
559 SEC_FILE_READ_DATA|
560 SEC_FILE_WRITE_DATA|
561 SEC_STD_DELETE,
562 FILE_ATTRIBUTE_NORMAL,
563 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
564 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
566 if (fnum1 == -1) {
567 printf("(%s) open of %s failed (%s)\n",
568 __location__, fname, smbcli_errstr(cli1->tree));
569 correct = False;
570 goto fail;
573 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
574 SEC_FILE_READ_DATA|
575 SEC_FILE_WRITE_DATA|
576 SEC_STD_DELETE,
577 FILE_ATTRIBUTE_NORMAL,
578 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
579 NTCREATEX_DISP_OPEN, 0, 0);
581 if (fnum2 == -1) {
582 printf("(%s) open of %s failed (%s)\n",
583 __location__, fname, smbcli_errstr(cli1->tree));
584 correct = False;
585 goto fail;
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",
590 __location__);
591 correct = False;
592 goto fail;
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));
601 correct = False;
602 goto fail;
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));
611 correct = False;
612 goto fail;
615 /* This should fail.. */
616 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
617 if (fnum1 != -1) {
618 printf("(%s) open of %s succeeded should have been deleted on close !\n",
619 __location__, fname);
620 correct = False;
621 } else {
622 printf("eighth delete on close test succeeded.\n");
625 fail:
627 return correct;
630 /* Test 9 ... */
631 static BOOL deltest9(struct smbcli_state *cli1, struct smbcli_state *cli2)
633 int fnum1 = -1;
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);
645 if (fnum1 != -1) {
646 printf("(%s) open of %s succeeded should have failed!\n",
647 __location__, fname);
648 return False;
651 printf("ninth delete on close test succeeded.\n");
652 return True;
655 /* Test 10 ... */
656 static BOOL deltest10(struct smbcli_state *cli1, struct smbcli_state *cli2)
658 int fnum1 = -1;
659 BOOL correct = True;
661 del_clean_area(cli1, cli2);
663 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
664 SEC_FILE_READ_DATA|
665 SEC_FILE_WRITE_DATA|
666 SEC_STD_DELETE,
667 FILE_ATTRIBUTE_NORMAL,
668 NTCREATEX_SHARE_ACCESS_NONE,
669 NTCREATEX_DISP_OVERWRITE_IF,
670 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
671 if (fnum1 == -1) {
672 printf("(%s) open of %s failed (%s)\n",
673 __location__, fname, smbcli_errstr(cli1->tree));
674 correct = False;
675 goto fail;
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));
682 correct = False;
683 goto fail;
686 /* This should fail.. */
687 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
688 if (fnum1 != -1) {
689 printf("(%s) open of %s succeeded should have been deleted on close !\n",
690 __location__, fname);
691 correct = False;
692 goto fail;
693 } else {
694 printf("tenth delete on close test succeeded.\n");
697 fail:
699 return correct;
702 /* Test 11 ... */
703 static BOOL deltest11(struct smbcli_state *cli1, struct smbcli_state *cli2)
705 int fnum1 = -1;
706 NTSTATUS status;
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,
713 SEC_RIGHTS_FILE_ALL,
714 FILE_ATTRIBUTE_READONLY,
715 NTCREATEX_SHARE_ACCESS_NONE,
716 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
718 if (fnum1 == -1) {
719 printf("(%s) open of %s failed (%s)\n",
720 __location__, fname, smbcli_errstr(cli1->tree));
721 return False;
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));
729 return False;
732 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
733 printf("(%s) close failed (%s)\n",
734 __location__, smbcli_errstr(cli1->tree));
735 return False;
738 printf("eleventh delete on close test succeeded.\n");
739 return True;
742 /* Test 12 ... */
743 static BOOL deltest12(struct smbcli_state *cli1, struct smbcli_state *cli2)
745 int fnum1 = -1;
746 NTSTATUS status;
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,
754 SEC_RIGHTS_FILE_ALL,
755 FILE_ATTRIBUTE_READONLY,
756 NTCREATEX_SHARE_ACCESS_DELETE,
757 NTCREATEX_DISP_OVERWRITE_IF,
758 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
760 if (fnum1 != -1) {
761 printf("(%s) open of %s succeeded. Should fail with "
762 "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
763 smbcli_close(cli1->tree, fnum1);
764 return False;
765 } else {
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 "
770 "instead)\n",
771 __location__, smbcli_errstr(cli1->tree));
772 return False;
776 printf("twelvth delete on close test succeeded.\n");
777 return True;
780 /* Test 13 ... */
781 static BOOL deltest13(struct smbcli_state *cli1, struct smbcli_state *cli2)
783 int fnum1 = -1;
784 int fnum2 = -1;
785 BOOL correct = True;
787 del_clean_area(cli1, cli2);
789 /* Test 13: Does resetting the delete on close flag affect a second
790 * fd? */
792 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
793 SEC_FILE_READ_DATA|
794 SEC_FILE_WRITE_DATA|
795 SEC_STD_DELETE,
796 FILE_ATTRIBUTE_NORMAL,
797 NTCREATEX_SHARE_ACCESS_READ|
798 NTCREATEX_SHARE_ACCESS_WRITE|
799 NTCREATEX_SHARE_ACCESS_DELETE,
800 NTCREATEX_DISP_OVERWRITE_IF,
801 0, 0);
803 if (fnum1 == -1) {
804 printf("(%s) open of %s failed (%s)\n",
805 __location__, fname, smbcli_errstr(cli1->tree));
806 correct = False;
807 goto fail;
810 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
811 SEC_FILE_READ_DATA|
812 SEC_FILE_WRITE_DATA|
813 SEC_STD_DELETE,
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);
820 if (fnum2 == -1) {
821 printf("(%s) open of %s failed (%s)\n",
822 __location__, fname, smbcli_errstr(cli2->tree));
823 correct = False;
824 goto fail;
827 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1,
828 True))) {
829 printf("(%s) setting delete_on_close on file failed !\n",
830 __location__);
831 correct = False;
832 goto fail;
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,
839 False))) {
840 printf("(%s) setting delete_on_close on file failed !\n",
841 __location__);
842 correct = False;
843 goto fail;
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));
852 correct = False;
853 goto fail;
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));
859 correct = False;
860 goto fail;
863 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
865 if (fnum1 == -1) {
866 printf("(%s) open of %s failed!\n",
867 __location__, fname);
868 correct = False;
869 goto fail;
872 printf("thirteenth delete on close test succeeded.\n");
874 fail:
876 return correct;
879 /* Test 14 ... */
880 static BOOL deltest14(struct smbcli_state *cli1, struct smbcli_state *cli2)
882 int dnum1 = -1;
883 BOOL correct = True;
885 del_clean_area(cli1, cli2);
887 /* Test 14 -- directory */
889 dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
890 SEC_FILE_READ_DATA|
891 SEC_FILE_WRITE_DATA|
892 SEC_STD_DELETE,
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);
898 if (dnum1 == -1) {
899 printf("(%s) open of %s failed: %s!\n",
900 __location__, dname, smbcli_errstr(cli1->tree));
901 correct = False;
902 goto fail;
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",
908 __location__);
909 correct = False;
910 goto fail;
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,
918 SEC_FILE_READ_DATA|
919 SEC_FILE_WRITE_DATA|
920 SEC_STD_DELETE,
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);
926 if (dnum1 != -1) {
927 printf("(%s) setting delete_on_close on file succeeded !\n",
928 __location__);
929 correct = False;
930 goto fail;
933 printf("fourteenth delete on close test succeeded.\n");
935 fail:
937 return correct;
940 /* Test 15 ... */
941 static BOOL deltest15(struct smbcli_state *cli1, struct smbcli_state *cli2)
943 int fnum1 = -1;
944 int fnum2 = -1;
945 BOOL correct = True;
946 NTSTATUS status;
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,
957 SEC_FILE_READ_DATA,
958 FILE_ATTRIBUTE_NORMAL,
959 NTCREATEX_SHARE_ACCESS_READ|
960 NTCREATEX_SHARE_ACCESS_WRITE|
961 NTCREATEX_SHARE_ACCESS_DELETE,
962 NTCREATEX_DISP_OVERWRITE_IF,
963 0, 0);
965 if (fnum1 == -1) {
966 printf("(%s) open - 1 of %s failed (%s)\n",
967 __location__, fname, smbcli_errstr(cli1->tree));
968 correct = False;
969 goto fail;
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));
977 correct = False;
978 goto fail;
981 fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0,
982 SEC_GENERIC_ALL,
983 FILE_ATTRIBUTE_NORMAL,
984 NTCREATEX_SHARE_ACCESS_READ|
985 NTCREATEX_SHARE_ACCESS_WRITE|
986 NTCREATEX_SHARE_ACCESS_DELETE,
987 NTCREATEX_DISP_OVERWRITE_IF,
988 0, 0);
990 if (fnum2 == -1) {
991 printf("(%s) open - 1 of %s failed (%s)\n",
992 __location__, fname_new, smbcli_errstr(cli1->tree));
993 correct = False;
994 goto fail;
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",
1001 __location__);
1002 correct = False;
1003 goto fail;
1006 smbcli_close(cli2->tree, fnum2);
1008 /* The file should be around under the new name, there's a second
1009 * handle open */
1011 correct &= check_delete_on_close(cli1, fnum1, fname_new, True, __location__);
1013 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
1014 SEC_GENERIC_ALL,
1015 FILE_ATTRIBUTE_NORMAL,
1016 NTCREATEX_SHARE_ACCESS_READ|
1017 NTCREATEX_SHARE_ACCESS_WRITE|
1018 NTCREATEX_SHARE_ACCESS_DELETE,
1019 NTCREATEX_DISP_OVERWRITE_IF,
1020 0, 0);
1022 if (fnum2 == -1) {
1023 printf("(%s) open - 1 of %s failed (%s)\n",
1024 __location__, fname, smbcli_errstr(cli1->tree));
1025 correct = False;
1026 goto fail;
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,
1035 SEC_FILE_READ_EA,
1036 FILE_ATTRIBUTE_NORMAL,
1037 NTCREATEX_SHARE_ACCESS_READ|
1038 NTCREATEX_SHARE_ACCESS_WRITE|
1039 NTCREATEX_SHARE_ACCESS_DELETE,
1040 NTCREATEX_DISP_OPEN,
1041 0, 0);
1043 if (fnum1 == -1) {
1044 printf("(%s) open - 1 of %s failed (%s)\n",
1045 __location__, fname, smbcli_errstr(cli1->tree));
1046 correct = False;
1047 goto fail;
1050 smbcli_close(cli1->tree, fnum1);
1052 fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0,
1053 SEC_FILE_READ_EA,
1054 FILE_ATTRIBUTE_NORMAL,
1055 NTCREATEX_SHARE_ACCESS_READ|
1056 NTCREATEX_SHARE_ACCESS_WRITE|
1057 NTCREATEX_SHARE_ACCESS_DELETE,
1058 NTCREATEX_DISP_OPEN,
1059 0, 0);
1061 if (fnum1 != -1) {
1062 printf("(%s) smbcli_open succeeded, should have "
1063 "failed\n", __location__);
1064 smbcli_close(cli1->tree, fnum1);
1065 correct = False;
1066 goto fail;
1069 printf("fifteenth delete on close test succeeded.\n");
1071 fail:
1073 return correct;
1076 /* Test 16 ... */
1077 static BOOL deltest16(struct smbcli_state *cli1, struct smbcli_state *cli2)
1079 int fnum1 = -1;
1080 int fnum2 = -1;
1081 BOOL correct = True;
1083 del_clean_area(cli1, cli2);
1085 /* Test 16. */
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);
1103 if (fnum1 == -1) {
1104 printf("(%s) open - 1 of %s failed (%s)\n",
1105 __location__, fname, smbcli_errstr(cli1->tree));
1106 correct = False;
1107 goto fail;
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,
1125 0, 0);
1128 /* Should work. */
1129 if (fnum2 == -1) {
1130 printf("(%s) open - 1 of %s failed (%s)\n",
1131 __location__, fname, smbcli_errstr(cli1->tree));
1132 correct = False;
1133 goto fail;
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);
1150 if (fnum1 != -1) {
1151 printf("(%s) open of %s succeeded (should fail)\n",
1152 __location__, fname);
1153 correct = False;
1154 goto fail;
1157 printf("sixteenth delete on close test succeeded.\n");
1159 fail:
1161 return correct;
1164 /* Test 17 ... */
1165 static BOOL deltest17(struct smbcli_state *cli1, struct smbcli_state *cli2)
1167 int fnum1 = -1;
1168 int fnum2 = -1;
1169 BOOL correct = True;
1171 del_clean_area(cli1, cli2);
1173 /* Test 17. */
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,
1189 0, 0);
1190 if (fnum1 == -1) {
1191 printf("(%s) open - 1 of %s failed (%s)\n",
1192 __location__, fname, smbcli_errstr(cli1->tree));
1193 correct = False;
1194 goto fail;
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);
1210 if (fnum1 == -1) {
1211 printf("(%s) open - 1 of %s failed (%s)\n",
1212 __location__, fname, smbcli_errstr(cli1->tree));
1213 correct = False;
1214 goto fail;
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|
1223 SEC_STD_DELETE,
1224 FILE_ATTRIBUTE_NORMAL,
1225 NTCREATEX_SHARE_ACCESS_READ|
1226 NTCREATEX_SHARE_ACCESS_WRITE|
1227 NTCREATEX_SHARE_ACCESS_DELETE,
1228 NTCREATEX_DISP_OPEN,
1229 0, 0);
1231 /* Should work. */
1232 if (fnum2 == -1) {
1233 printf("(%s) open - 1 of %s failed (%s)\n",
1234 __location__, fname, smbcli_errstr(cli1->tree));
1235 correct = False;
1236 goto fail;
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);
1251 if (fnum1 == -1) {
1252 printf("(%s) open of %s failed (should succeed) - %s\n",
1253 __location__, fname, smbcli_errstr(cli1->tree));
1254 correct = False;
1255 goto fail;
1258 printf("seventeenth delete on close test succeeded.\n");
1260 fail:
1262 return correct;
1265 /* Test 18 ... */
1266 static BOOL deltest18(struct smbcli_state *cli1, struct smbcli_state *cli2)
1268 int fnum1 = -1;
1269 int fnum2 = -1;
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,
1284 SEC_FILE_READ_DATA|
1285 SEC_FILE_WRITE_DATA|
1286 SEC_STD_DELETE,
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);
1294 if (fnum1 == -1) {
1295 printf("(%s) open - 1 of %s failed (%s)\n",
1296 __location__, dname, smbcli_errstr(cli1->tree));
1297 correct = False;
1298 goto fail;
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);
1315 /* Should work. */
1316 if (fnum2 == -1) {
1317 printf("(%s) open - 1 of %s failed (%s)\n",
1318 __location__, dname, smbcli_errstr(cli1->tree));
1319 correct = False;
1320 goto fail;
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);
1341 if (fnum1 != -1) {
1342 printf("(%s) open of %s succeeded (should fail)\n",
1343 __location__, dname);
1344 correct = False;
1345 goto fail;
1348 printf("eighteenth delete on close test succeeded.\n");
1350 fail:
1352 return correct;
1355 /* Test 19 ... */
1356 static BOOL deltest19(struct smbcli_state *cli1, struct smbcli_state *cli2)
1358 int fnum1 = -1;
1359 int fnum2 = -1;
1360 BOOL correct = True;
1362 del_clean_area(cli1, cli2);
1364 /* Test 19. */
1366 smbcli_deltree(cli1->tree, dname);
1368 /* Firstly open and create with all access */
1369 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1370 SEC_FILE_READ_DATA|
1371 SEC_FILE_WRITE_DATA|
1372 SEC_STD_DELETE,
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);
1380 if (fnum1 == -1) {
1381 printf("(%s) open - 1 of %s failed (%s)\n",
1382 __location__, dname, smbcli_errstr(cli1->tree));
1383 correct = False;
1384 goto fail;
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,
1392 SEC_FILE_READ_DATA|
1393 SEC_FILE_WRITE_DATA|
1394 SEC_STD_DELETE,
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);
1402 if (fnum1 == -1) {
1403 printf("(%s) open - 1 of %s failed (%s)\n",
1404 __location__, fname, smbcli_errstr(cli1->tree));
1405 correct = False;
1406 goto fail;
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);
1422 /* Should work. */
1423 if (fnum2 == -1) {
1424 printf("(%s) open - 1 of %s failed (%s)\n",
1425 __location__, dname, smbcli_errstr(cli1->tree));
1426 correct = False;
1427 goto fail;
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);
1448 if (fnum1 != -1) {
1449 printf("(%s) open of %s succeeded (should fail)\n",
1450 __location__, dname);
1451 correct = False;
1452 goto fail;
1455 printf("nineteenth delete on close test succeeded.\n");
1457 fail:
1459 return correct;
1462 /* Test 20 ... */
1463 static BOOL deltest20(struct smbcli_state *cli1, struct smbcli_state *cli2)
1465 int fnum1 = -1;
1466 int dnum1 = -1;
1467 BOOL correct = True;
1468 NTSTATUS status;
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,
1477 SEC_FILE_READ_DATA|
1478 SEC_FILE_WRITE_DATA|
1479 SEC_STD_DELETE,
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);
1486 if (dnum1 == -1) {
1487 printf("(%s) open of %s failed: %s!\n",
1488 __location__, dname, smbcli_errstr(cli1->tree));
1489 correct = False;
1490 goto fail;
1493 correct &= check_delete_on_close(cli1, dnum1, dname, False, __location__);
1494 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1497 char *fullname;
1498 asprintf(&fullname, "\\%s%s", dname, fname);
1499 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1500 DENY_NONE);
1501 if (fnum1 != -1) {
1502 printf("(%s) smbcli_open succeeded, should have "
1503 "failed with NT_STATUS_DELETE_PENDING\n",
1504 __location__);
1505 correct = False;
1506 goto fail;
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));
1514 correct = False;
1515 goto fail;
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",
1522 __location__);
1523 correct = False;
1524 goto fail;
1528 char *fullname;
1529 asprintf(&fullname, "\\%s%s", dname, fname);
1530 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1531 DENY_NONE);
1532 if (fnum1 == -1) {
1533 printf("(%s) smbcli_open failed: %s\n",
1534 __location__, smbcli_errstr(cli1->tree));
1535 correct = False;
1536 goto fail;
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));
1547 correct = False;
1548 goto fail;
1551 smbcli_close(cli1->tree, dnum1);
1553 printf("twentieth delete on close test succeeded.\n");
1555 fail:
1557 return correct;
1560 /* Test 21 ... */
1561 static BOOL deltest21(struct smbcli_state **ppcli1, struct smbcli_state **ppcli2)
1563 int fnum1 = -1;
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);
1577 if (fnum1 == -1) {
1578 printf("(%s) open of %s failed (%s)\n",
1579 __location__, fname, smbcli_errstr(cli1->tree));
1580 return False;
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));
1586 return False;
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);
1595 fnum1 = -1;
1597 if (!torture_open_connection(ppcli1)) {
1598 return False;
1601 cli1 = *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,
1611 0, 0);
1613 CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1615 printf("twenty-first delete on close test succeeded.\n");
1617 fail:
1619 return correct;
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)) {
1634 return False;
1637 if (!torture_open_connection(&cli2)) {
1638 printf("(%s) failed to open second connection.\n",
1639 __location__);
1640 correct = False;
1641 goto fail;
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);
1668 if (!correct) {
1669 printf("Failed delete test\n");
1670 } else {
1671 printf("delete test ok !\n");
1674 fail:
1675 del_clean_area(cli1, cli2);
1677 if (!torture_close_connection(cli1)) {
1678 correct = False;
1680 if (!torture_close_connection(cli2)) {
1681 correct = False;
1683 return correct;