r17020: pass the real error to the failing requests
[Samba.git] / source / torture / basic / delete.c
blob445333ca6fac3fa2e200ef71a8badcf715dc2092
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,
48 RAW_SEARCH_TRANS2,
49 RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
50 FILE_ATTRIBUTE_DIRECTORY,
51 &data);
52 if (!NT_STATUS_IS_OK(status)) {
53 printf("(%s) single_search failed (%s)\n",
54 where, nt_errstr(status));
55 res = False;
56 goto done;
59 if (fnum != -1) {
60 union smb_fileinfo io;
61 int nlink = expect_it ? 0 : 1;
63 io.all_info.level = RAW_FILEINFO_ALL_INFO;
64 io.all_info.in.file.fnum = fnum;
66 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
67 if (!NT_STATUS_IS_OK(status)) {
68 printf("(%s) qfileinfo failed (%s)\n", where,
69 nt_errstr(status));
70 res = False;
71 goto done;
74 if (expect_it != io.all_info.out.delete_pending) {
75 printf("%s - Expected del_on_close flag %d, qfileinfo/all_info gave %d\n",
76 where, expect_it, io.all_info.out.delete_pending);
77 res = False;
78 goto done;
81 if (nlink != io.all_info.out.nlink) {
82 printf("%s - Expected nlink %d, qfileinfo/all_info gave %d\n",
83 where, nlink, io.all_info.out.nlink);
84 res = False;
85 goto done;
88 io.standard_info.level = RAW_FILEINFO_STANDARD_INFO;
89 io.standard_info.in.file.fnum = fnum;
91 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
92 if (!NT_STATUS_IS_OK(status)) {
93 printf("(%s) qpathinfo failed (%s)\n", where,
94 nt_errstr(status));
95 res = False;
96 goto done;
99 if (expect_it != io.standard_info.out.delete_pending) {
100 printf("%s - Expected del_on_close flag %d, qfileinfo/standard_info gave %d\n",
101 where, expect_it, io.standard_info.out.delete_pending);
102 res = False;
103 goto done;
106 if (nlink != io.standard_info.out.nlink) {
107 printf("%s - Expected nlink %d, qfileinfo/standard_info gave %d\n",
108 where, nlink, io.all_info.out.nlink);
109 res = False;
110 goto done;
115 status = smbcli_qpathinfo(cli->tree, fname,
116 &c_time, &a_time, &m_time,
117 &size, &mode);
119 if (expect_it) {
120 if (!NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
121 printf("(%s) qpathinfo did not give correct error "
122 "code (%s) -- NT_STATUS_DELETE_PENDING "
123 "expected\n", where,
124 nt_errstr(status));
125 res = False;
126 goto done;
128 } else {
129 if (!NT_STATUS_IS_OK(status)) {
130 printf("(%s) qpathinfo failed (%s)\n", where,
131 nt_errstr(status));
132 res = False;
133 goto done;
137 done:
138 talloc_free(mem_ctx);
139 return res;
142 #define CHECK_STATUS(_cli, _expected) do { \
143 if (!NT_STATUS_EQUAL(_cli->tree->session->transport->error.e.nt_status, _expected)) { \
144 printf("(%d) Incorrect status %s - should be %s\n", \
145 __LINE__, nt_errstr(_cli->tree->session->transport->error.e.nt_status), nt_errstr(_expected)); \
146 correct = False; \
147 goto fail; \
148 }} while (0)
150 static const char *fname = "\\delete.file";
151 static const char *fname_new = "\\delete.new";
152 static const char *dname = "\\delete.dir";
154 static void del_clean_area(struct smbcli_state *cli1, struct smbcli_state *cli2)
156 smbcli_deltree(cli1->tree, dname);
157 smbcli_setatr(cli1->tree, fname, 0, 0);
158 smbcli_unlink(cli1->tree, fname);
159 smbcli_setatr(cli1->tree, fname_new, 0, 0);
160 smbcli_unlink(cli1->tree, fname_new);
162 smb_raw_exit(cli1->session);
163 smb_raw_exit(cli2->session);
166 /* Test 1 - this should delete the file on close. */
168 static BOOL deltest1(struct smbcli_state *cli1, struct smbcli_state *cli2)
170 int fnum1 = -1;
172 del_clean_area(cli1, cli2);
174 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
175 SEC_RIGHTS_FILE_ALL,
176 FILE_ATTRIBUTE_NORMAL,
177 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
178 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
180 if (fnum1 == -1) {
181 printf("(%s) open of %s failed (%s)\n",
182 __location__, fname, smbcli_errstr(cli1->tree));
183 return False;
186 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
187 printf("(%s) close failed (%s)\n",
188 __location__, smbcli_errstr(cli1->tree));
189 return False;
192 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
193 if (fnum1 != -1) {
194 printf("(%s) open of %s succeeded (should fail)\n",
195 __location__, fname);
196 return False;
199 printf("first delete on close test succeeded.\n");
200 return True;
203 /* Test 2 - this should delete the file on close. */
204 static BOOL deltest2(struct smbcli_state *cli1, struct smbcli_state *cli2)
206 int fnum1 = -1;
208 del_clean_area(cli1, cli2);
210 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
211 SEC_RIGHTS_FILE_ALL,
212 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
213 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
215 if (fnum1 == -1) {
216 printf("(%s) open of %s failed (%s)\n",
217 __location__, fname, smbcli_errstr(cli1->tree));
218 return False;
221 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
222 printf("(%s) setting delete_on_close failed (%s)\n",
223 __location__, smbcli_errstr(cli1->tree));
224 return False;
227 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
228 printf("(%s) close failed (%s)\n",
229 __location__, smbcli_errstr(cli1->tree));
230 return False;
233 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
234 if (fnum1 != -1) {
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));
240 return False;
242 smbcli_unlink(cli1->tree, fname);
243 } else {
244 printf("second delete on close test succeeded.\n");
246 return True;
249 /* Test 3 - ... */
250 static BOOL deltest3(struct smbcli_state *cli1, struct smbcli_state *cli2)
252 int fnum1 = -1;
253 int fnum2 = -1;
255 del_clean_area(cli1, cli2);
257 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
258 SEC_RIGHTS_FILE_ALL,
259 FILE_ATTRIBUTE_NORMAL,
260 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
261 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
263 if (fnum1 == -1) {
264 printf("(%s) open - 1 of %s failed (%s)\n",
265 __location__, fname, smbcli_errstr(cli1->tree));
266 return False;
269 /* This should fail with a sharing violation - open for delete is only compatible
270 with SHARE_DELETE. */
272 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
273 SEC_RIGHTS_FILE_READ,
274 FILE_ATTRIBUTE_NORMAL,
275 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
276 NTCREATEX_DISP_OPEN, 0, 0);
278 if (fnum2 != -1) {
279 printf("(%s) open - 2 of %s succeeded - should have failed.\n",
280 __location__, fname);
281 return False;
284 /* This should succeed. */
286 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
287 SEC_RIGHTS_FILE_READ,
288 FILE_ATTRIBUTE_NORMAL,
289 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
290 NTCREATEX_DISP_OPEN, 0, 0);
292 if (fnum2 == -1) {
293 printf("(%s) open - 2 of %s failed (%s)\n",
294 __location__, fname, smbcli_errstr(cli1->tree));
295 return False;
298 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
299 printf("(%s) setting delete_on_close failed (%s)\n",
300 __location__, smbcli_errstr(cli1->tree));
301 return False;
304 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
305 printf("(%s) close 1 failed (%s)\n",
306 __location__, smbcli_errstr(cli1->tree));
307 return False;
310 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
311 printf("(%s) close 2 failed (%s)\n",
312 __location__, smbcli_errstr(cli1->tree));
313 return False;
316 /* This should fail - file should no longer be there. */
318 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
319 if (fnum1 != -1) {
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);
327 return False;
328 } else {
329 printf("third delete on close test succeeded.\n");
331 return True;
334 /* Test 4 ... */
335 static BOOL deltest4(struct smbcli_state *cli1, struct smbcli_state *cli2)
337 int fnum1 = -1;
338 int fnum2 = -1;
339 BOOL correct = True;
341 del_clean_area(cli1, cli2);
343 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
344 SEC_FILE_READ_DATA |
345 SEC_FILE_WRITE_DATA |
346 SEC_STD_DELETE,
347 FILE_ATTRIBUTE_NORMAL,
348 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
349 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
351 if (fnum1 == -1) {
352 printf("(%s) open of %s failed (%s)\n",
353 __location__, fname, smbcli_errstr(cli1->tree));
354 return False;
357 /* This should succeed. */
358 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
359 SEC_RIGHTS_FILE_READ,
360 FILE_ATTRIBUTE_NORMAL,
361 NTCREATEX_SHARE_ACCESS_READ |
362 NTCREATEX_SHARE_ACCESS_WRITE |
363 NTCREATEX_SHARE_ACCESS_DELETE,
364 NTCREATEX_DISP_OPEN, 0, 0);
365 if (fnum2 == -1) {
366 printf("(%s) open - 2 of %s failed (%s)\n",
367 __location__, fname, smbcli_errstr(cli1->tree));
368 return False;
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));
374 return False;
377 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
378 printf("(%s) setting delete_on_close failed (%s)\n",
379 __location__, smbcli_errstr(cli1->tree));
380 return False;
383 /* This should fail - no more opens once delete on close set. */
384 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
385 SEC_RIGHTS_FILE_READ,
386 FILE_ATTRIBUTE_NORMAL,
387 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
388 NTCREATEX_DISP_OPEN, 0, 0);
389 if (fnum2 != -1) {
390 printf("(%s) open - 3 of %s succeeded ! Should have failed.\n",
391 __location__, fname );
392 return False;
394 CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
396 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
397 printf("(%s) close - 2 failed (%s)\n",
398 __location__, smbcli_errstr(cli1->tree));
399 return False;
402 printf("fourth delete on close test succeeded.\n");
404 fail:
406 return correct;
409 /* Test 5 ... */
410 static BOOL deltest5(struct smbcli_state *cli1, struct smbcli_state *cli2)
412 int fnum1 = -1;
414 del_clean_area(cli1, cli2);
416 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
417 if (fnum1 == -1) {
418 printf("(%s) open of %s failed (%s)\n",
419 __location__, fname, smbcli_errstr(cli1->tree));
420 return False;
423 /* This should fail - only allowed on NT opens with DELETE access. */
425 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
426 printf("(%s) setting delete_on_close on OpenX file succeeded - should fail !\n",
427 __location__);
428 return False;
431 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
432 printf("(%s) close - 2 failed (%s)\n",
433 __location__, smbcli_errstr(cli1->tree));
434 return False;
437 printf("fifth delete on close test succeeded.\n");
438 return True;
441 /* Test 6 ... */
442 static BOOL deltest6(struct smbcli_state *cli1, struct smbcli_state *cli2)
444 int fnum1 = -1;
446 del_clean_area(cli1, cli2);
448 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
449 SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
450 FILE_ATTRIBUTE_NORMAL,
451 NTCREATEX_SHARE_ACCESS_READ |
452 NTCREATEX_SHARE_ACCESS_WRITE |
453 NTCREATEX_SHARE_ACCESS_DELETE,
454 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
456 if (fnum1 == -1) {
457 printf("(%s) open of %s failed (%s)\n",
458 __location__, fname, smbcli_errstr(cli1->tree));
459 return False;
462 /* This should fail - only allowed on NT opens with DELETE access. */
464 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
465 printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
466 __location__);
467 return False;
470 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
471 printf("(%s) close - 2 failed (%s)\n",
472 __location__, smbcli_errstr(cli1->tree));
473 return False;
476 printf("sixth delete on close test succeeded.\n");
477 return True;
480 /* Test 7 ... */
481 static BOOL deltest7(struct smbcli_state *cli1, struct smbcli_state *cli2)
483 int fnum1 = -1;
484 BOOL correct = True;
486 del_clean_area(cli1, cli2);
488 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
489 SEC_FILE_READ_DATA |
490 SEC_FILE_WRITE_DATA |
491 SEC_STD_DELETE,
492 FILE_ATTRIBUTE_NORMAL, 0,
493 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
495 if (fnum1 == -1) {
496 printf("(%s) open of %s failed (%s)\n",
497 __location__, fname, smbcli_errstr(cli1->tree));
498 correct = False;
499 goto fail;
502 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
503 printf("(%s) setting delete_on_close on file failed !\n",
504 __location__);
505 correct = False;
506 goto fail;
509 correct &= check_delete_on_close(cli1, fnum1, fname, True, __location__);
511 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
512 printf("(%s) unsetting delete_on_close on file failed !\n",
513 __location__);
514 correct = False;
515 goto fail;
518 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
520 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
521 printf("(%s) close - 2 failed (%s)\n",
522 __location__, smbcli_errstr(cli1->tree));
523 correct = False;
524 goto fail;
527 /* This next open should succeed - we reset the flag. */
529 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
530 if (fnum1 == -1) {
531 printf("(%s) open of %s failed (%s)\n",
532 __location__, fname, smbcli_errstr(cli1->tree));
533 correct = False;
534 goto fail;
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));
540 correct = False;
541 goto fail;
544 printf("seventh delete on close test succeeded.\n");
546 fail:
548 return correct;
551 /* Test 8 ... */
552 static BOOL deltest8(struct smbcli_state *cli1, struct smbcli_state *cli2)
554 int fnum1 = -1;
555 int fnum2 = -1;
556 BOOL correct = True;
558 del_clean_area(cli1, cli2);
560 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
561 SEC_FILE_READ_DATA|
562 SEC_FILE_WRITE_DATA|
563 SEC_STD_DELETE,
564 FILE_ATTRIBUTE_NORMAL,
565 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
566 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
568 if (fnum1 == -1) {
569 printf("(%s) open of %s failed (%s)\n",
570 __location__, fname, smbcli_errstr(cli1->tree));
571 correct = False;
572 goto fail;
575 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
576 SEC_FILE_READ_DATA|
577 SEC_FILE_WRITE_DATA|
578 SEC_STD_DELETE,
579 FILE_ATTRIBUTE_NORMAL,
580 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
581 NTCREATEX_DISP_OPEN, 0, 0);
583 if (fnum2 == -1) {
584 printf("(%s) open of %s failed (%s)\n",
585 __location__, fname, smbcli_errstr(cli1->tree));
586 correct = False;
587 goto fail;
590 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
591 printf("(%s) setting delete_on_close on file failed !\n",
592 __location__);
593 correct = False;
594 goto fail;
597 correct &= check_delete_on_close(cli1, fnum1, fname, True, __location__);
598 correct &= check_delete_on_close(cli2, fnum2, fname, True, __location__);
600 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
601 printf("(%s) close - 1 failed (%s)\n",
602 __location__, smbcli_errstr(cli1->tree));
603 correct = False;
604 goto fail;
607 correct &= check_delete_on_close(cli1, -1, fname, True, __location__);
608 correct &= check_delete_on_close(cli2, fnum2, fname, True, __location__);
610 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
611 printf("(%s) close - 2 failed (%s)\n",
612 __location__, smbcli_errstr(cli2->tree));
613 correct = False;
614 goto fail;
617 /* This should fail.. */
618 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
619 if (fnum1 != -1) {
620 printf("(%s) open of %s succeeded should have been deleted on close !\n",
621 __location__, fname);
622 correct = False;
623 } else {
624 printf("eighth delete on close test succeeded.\n");
627 fail:
629 return correct;
632 /* Test 9 ... */
633 static BOOL deltest9(struct smbcli_state *cli1, struct smbcli_state *cli2)
635 int fnum1 = -1;
637 del_clean_area(cli1, cli2);
639 /* This should fail - we need to set DELETE_ACCESS. */
640 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
641 SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
642 FILE_ATTRIBUTE_NORMAL,
643 NTCREATEX_SHARE_ACCESS_NONE,
644 NTCREATEX_DISP_OVERWRITE_IF,
645 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
647 if (fnum1 != -1) {
648 printf("(%s) open of %s succeeded should have failed!\n",
649 __location__, fname);
650 return False;
653 printf("ninth delete on close test succeeded.\n");
654 return True;
657 /* Test 10 ... */
658 static BOOL deltest10(struct smbcli_state *cli1, struct smbcli_state *cli2)
660 int fnum1 = -1;
661 BOOL correct = True;
663 del_clean_area(cli1, cli2);
665 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
666 SEC_FILE_READ_DATA|
667 SEC_FILE_WRITE_DATA|
668 SEC_STD_DELETE,
669 FILE_ATTRIBUTE_NORMAL,
670 NTCREATEX_SHARE_ACCESS_NONE,
671 NTCREATEX_DISP_OVERWRITE_IF,
672 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
673 if (fnum1 == -1) {
674 printf("(%s) open of %s failed (%s)\n",
675 __location__, fname, smbcli_errstr(cli1->tree));
676 correct = False;
677 goto fail;
680 /* This should delete the file. */
681 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
682 printf("(%s) close failed (%s)\n",
683 __location__, smbcli_errstr(cli1->tree));
684 correct = False;
685 goto fail;
688 /* This should fail.. */
689 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
690 if (fnum1 != -1) {
691 printf("(%s) open of %s succeeded should have been deleted on close !\n",
692 __location__, fname);
693 correct = False;
694 goto fail;
695 } else {
696 printf("tenth delete on close test succeeded.\n");
699 fail:
701 return correct;
704 /* Test 11 ... */
705 static BOOL deltest11(struct smbcli_state *cli1, struct smbcli_state *cli2)
707 int fnum1 = -1;
708 NTSTATUS status;
710 del_clean_area(cli1, cli2);
712 /* test 11 - does having read only attribute still allow delete on close. */
714 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
715 SEC_RIGHTS_FILE_ALL,
716 FILE_ATTRIBUTE_READONLY,
717 NTCREATEX_SHARE_ACCESS_NONE,
718 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
720 if (fnum1 == -1) {
721 printf("(%s) open of %s failed (%s)\n",
722 __location__, fname, smbcli_errstr(cli1->tree));
723 return False;
726 status = smbcli_nt_delete_on_close(cli1->tree, fnum1, True);
728 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
729 printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n",
730 __location__, smbcli_errstr(cli1->tree));
731 return False;
734 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
735 printf("(%s) close failed (%s)\n",
736 __location__, smbcli_errstr(cli1->tree));
737 return False;
740 printf("eleventh delete on close test succeeded.\n");
741 return True;
744 /* Test 12 ... */
745 static BOOL deltest12(struct smbcli_state *cli1, struct smbcli_state *cli2)
747 int fnum1 = -1;
748 NTSTATUS status;
750 del_clean_area(cli1, cli2);
752 /* test 12 - does having read only attribute still allow delete on
753 * close at time of open. */
755 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
756 SEC_RIGHTS_FILE_ALL,
757 FILE_ATTRIBUTE_READONLY,
758 NTCREATEX_SHARE_ACCESS_DELETE,
759 NTCREATEX_DISP_OVERWRITE_IF,
760 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
762 if (fnum1 != -1) {
763 printf("(%s) open of %s succeeded. Should fail with "
764 "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
765 smbcli_close(cli1->tree, fnum1);
766 return False;
767 } else {
768 status = smbcli_nt_error(cli1->tree);
769 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
770 printf("(%s) setting delete_on_close on open should "
771 "fail with NT_STATUS_CANNOT_DELETE. Got %s "
772 "instead)\n",
773 __location__, smbcli_errstr(cli1->tree));
774 return False;
778 printf("twelvth delete on close test succeeded.\n");
779 return True;
782 /* Test 13 ... */
783 static BOOL deltest13(struct smbcli_state *cli1, struct smbcli_state *cli2)
785 int fnum1 = -1;
786 int fnum2 = -1;
787 BOOL correct = True;
789 del_clean_area(cli1, cli2);
791 /* Test 13: Does resetting the delete on close flag affect a second
792 * fd? */
794 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
795 SEC_FILE_READ_DATA|
796 SEC_FILE_WRITE_DATA|
797 SEC_STD_DELETE,
798 FILE_ATTRIBUTE_NORMAL,
799 NTCREATEX_SHARE_ACCESS_READ|
800 NTCREATEX_SHARE_ACCESS_WRITE|
801 NTCREATEX_SHARE_ACCESS_DELETE,
802 NTCREATEX_DISP_OVERWRITE_IF,
803 0, 0);
805 if (fnum1 == -1) {
806 printf("(%s) open of %s failed (%s)\n",
807 __location__, fname, smbcli_errstr(cli1->tree));
808 correct = False;
809 goto fail;
812 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
813 SEC_FILE_READ_DATA|
814 SEC_FILE_WRITE_DATA|
815 SEC_STD_DELETE,
816 FILE_ATTRIBUTE_NORMAL,
817 NTCREATEX_SHARE_ACCESS_READ|
818 NTCREATEX_SHARE_ACCESS_WRITE|
819 NTCREATEX_SHARE_ACCESS_DELETE,
820 NTCREATEX_DISP_OPEN, 0, 0);
822 if (fnum2 == -1) {
823 printf("(%s) open of %s failed (%s)\n",
824 __location__, fname, smbcli_errstr(cli2->tree));
825 correct = False;
826 goto fail;
829 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1,
830 True))) {
831 printf("(%s) setting delete_on_close on file failed !\n",
832 __location__);
833 correct = False;
834 goto fail;
837 correct &= check_delete_on_close(cli1, fnum1, fname, True, __location__);
838 correct &= check_delete_on_close(cli2, fnum2, fname, True, __location__);
840 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli2->tree, fnum2,
841 False))) {
842 printf("(%s) setting delete_on_close on file failed !\n",
843 __location__);
844 correct = False;
845 goto fail;
848 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
849 correct &= check_delete_on_close(cli2, fnum2, fname, False, __location__);
851 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
852 printf("(%s) close - 1 failed (%s)\n",
853 __location__, smbcli_errstr(cli1->tree));
854 correct = False;
855 goto fail;
858 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
859 printf("(%s) close - 2 failed (%s)\n",
860 __location__, smbcli_errstr(cli2->tree));
861 correct = False;
862 goto fail;
865 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
867 if (fnum1 == -1) {
868 printf("(%s) open of %s failed!\n",
869 __location__, fname);
870 correct = False;
871 goto fail;
874 printf("thirteenth delete on close test succeeded.\n");
876 fail:
878 return correct;
881 /* Test 14 ... */
882 static BOOL deltest14(struct smbcli_state *cli1, struct smbcli_state *cli2)
884 int dnum1 = -1;
885 BOOL correct = True;
887 del_clean_area(cli1, cli2);
889 /* Test 14 -- directory */
891 dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
892 SEC_FILE_READ_DATA|
893 SEC_FILE_WRITE_DATA|
894 SEC_STD_DELETE,
895 FILE_ATTRIBUTE_DIRECTORY,
896 NTCREATEX_SHARE_ACCESS_READ|
897 NTCREATEX_SHARE_ACCESS_WRITE|
898 NTCREATEX_SHARE_ACCESS_DELETE,
899 NTCREATEX_DISP_CREATE, 0, 0);
900 if (dnum1 == -1) {
901 printf("(%s) open of %s failed: %s!\n",
902 __location__, dname, smbcli_errstr(cli1->tree));
903 correct = False;
904 goto fail;
907 correct &= check_delete_on_close(cli1, dnum1, dname, False, __location__);
908 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, dnum1, True))) {
909 printf("(%s) setting delete_on_close on file failed !\n",
910 __location__);
911 correct = False;
912 goto fail;
914 correct &= check_delete_on_close(cli1, dnum1, dname, True, __location__);
915 smbcli_close(cli1->tree, dnum1);
917 /* Now it should be gone... */
919 dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
920 SEC_FILE_READ_DATA|
921 SEC_FILE_WRITE_DATA|
922 SEC_STD_DELETE,
923 FILE_ATTRIBUTE_DIRECTORY,
924 NTCREATEX_SHARE_ACCESS_READ|
925 NTCREATEX_SHARE_ACCESS_WRITE|
926 NTCREATEX_SHARE_ACCESS_DELETE,
927 NTCREATEX_DISP_OPEN, 0, 0);
928 if (dnum1 != -1) {
929 printf("(%s) setting delete_on_close on file succeeded !\n",
930 __location__);
931 correct = False;
932 goto fail;
935 printf("fourteenth delete on close test succeeded.\n");
937 fail:
939 return correct;
942 /* Test 15 ... */
943 static BOOL deltest15(struct smbcli_state *cli1, struct smbcli_state *cli2)
945 int fnum1 = -1;
946 int fnum2 = -1;
947 BOOL correct = True;
948 NTSTATUS status;
950 del_clean_area(cli1, cli2);
952 /* Test 15: delete on close under rename */
954 smbcli_setatr(cli1->tree, fname, 0, 0);
955 smbcli_unlink(cli1->tree, fname);
956 smbcli_unlink(cli1->tree, fname_new);
958 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
959 SEC_FILE_READ_DATA,
960 FILE_ATTRIBUTE_NORMAL,
961 NTCREATEX_SHARE_ACCESS_READ|
962 NTCREATEX_SHARE_ACCESS_WRITE|
963 NTCREATEX_SHARE_ACCESS_DELETE,
964 NTCREATEX_DISP_OVERWRITE_IF,
965 0, 0);
967 if (fnum1 == -1) {
968 printf("(%s) open - 1 of %s failed (%s)\n",
969 __location__, fname, smbcli_errstr(cli1->tree));
970 correct = False;
971 goto fail;
974 status = smbcli_rename(cli2->tree, fname, fname_new);
976 if (!NT_STATUS_IS_OK(status)) {
977 printf("(%s) renaming failed: %s !\n",
978 __location__, nt_errstr(status));
979 correct = False;
980 goto fail;
983 fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0,
984 SEC_GENERIC_ALL,
985 FILE_ATTRIBUTE_NORMAL,
986 NTCREATEX_SHARE_ACCESS_READ|
987 NTCREATEX_SHARE_ACCESS_WRITE|
988 NTCREATEX_SHARE_ACCESS_DELETE,
989 NTCREATEX_DISP_OVERWRITE_IF,
990 0, 0);
992 if (fnum2 == -1) {
993 printf("(%s) open - 1 of %s failed (%s)\n",
994 __location__, fname_new, smbcli_errstr(cli1->tree));
995 correct = False;
996 goto fail;
999 status = smbcli_nt_delete_on_close(cli2->tree, fnum2, True);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 printf("(%s) setting delete_on_close on file failed !\n",
1003 __location__);
1004 correct = False;
1005 goto fail;
1008 smbcli_close(cli2->tree, fnum2);
1010 /* The file should be around under the new name, there's a second
1011 * handle open */
1013 correct &= check_delete_on_close(cli1, fnum1, fname_new, True, __location__);
1015 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
1016 SEC_GENERIC_ALL,
1017 FILE_ATTRIBUTE_NORMAL,
1018 NTCREATEX_SHARE_ACCESS_READ|
1019 NTCREATEX_SHARE_ACCESS_WRITE|
1020 NTCREATEX_SHARE_ACCESS_DELETE,
1021 NTCREATEX_DISP_OVERWRITE_IF,
1022 0, 0);
1024 if (fnum2 == -1) {
1025 printf("(%s) open - 1 of %s failed (%s)\n",
1026 __location__, fname, smbcli_errstr(cli1->tree));
1027 correct = False;
1028 goto fail;
1031 correct &= check_delete_on_close(cli2, fnum2, fname, False, __location__);
1033 smbcli_close(cli2->tree, fnum2);
1034 smbcli_close(cli1->tree, fnum1);
1036 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1037 SEC_FILE_READ_EA,
1038 FILE_ATTRIBUTE_NORMAL,
1039 NTCREATEX_SHARE_ACCESS_READ|
1040 NTCREATEX_SHARE_ACCESS_WRITE|
1041 NTCREATEX_SHARE_ACCESS_DELETE,
1042 NTCREATEX_DISP_OPEN,
1043 0, 0);
1045 if (fnum1 == -1) {
1046 printf("(%s) open - 1 of %s failed (%s)\n",
1047 __location__, fname, smbcli_errstr(cli1->tree));
1048 correct = False;
1049 goto fail;
1052 smbcli_close(cli1->tree, fnum1);
1054 fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0,
1055 SEC_FILE_READ_EA,
1056 FILE_ATTRIBUTE_NORMAL,
1057 NTCREATEX_SHARE_ACCESS_READ|
1058 NTCREATEX_SHARE_ACCESS_WRITE|
1059 NTCREATEX_SHARE_ACCESS_DELETE,
1060 NTCREATEX_DISP_OPEN,
1061 0, 0);
1063 if (fnum1 != -1) {
1064 printf("(%s) smbcli_open succeeded, should have "
1065 "failed\n", __location__);
1066 smbcli_close(cli1->tree, fnum1);
1067 correct = False;
1068 goto fail;
1071 printf("fifteenth delete on close test succeeded.\n");
1073 fail:
1075 return correct;
1078 /* Test 16 ... */
1079 static BOOL deltest16(struct smbcli_state *cli1, struct smbcli_state *cli2)
1081 int fnum1 = -1;
1082 int fnum2 = -1;
1083 BOOL correct = True;
1085 del_clean_area(cli1, cli2);
1087 /* Test 16. */
1089 /* Ensure the file doesn't already exist. */
1090 smbcli_close(cli1->tree, fnum1);
1091 smbcli_close(cli1->tree, fnum2);
1092 smbcli_setatr(cli1->tree, fname, 0, 0);
1093 smbcli_unlink(cli1->tree, fname);
1095 /* Firstly create with all access, but delete on close. */
1096 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1097 SEC_RIGHTS_FILE_ALL,
1098 FILE_ATTRIBUTE_NORMAL,
1099 NTCREATEX_SHARE_ACCESS_READ|
1100 NTCREATEX_SHARE_ACCESS_WRITE|
1101 NTCREATEX_SHARE_ACCESS_DELETE,
1102 NTCREATEX_DISP_CREATE,
1103 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1105 if (fnum1 == -1) {
1106 printf("(%s) open - 1 of %s failed (%s)\n",
1107 __location__, fname, smbcli_errstr(cli1->tree));
1108 correct = False;
1109 goto fail;
1112 /* The delete on close bit is *not* reported as being set. */
1113 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
1115 /* The delete on close bit is *not* reported as being set. */
1116 correct &= check_delete_on_close(cli1, -1, fname, False, __location__);
1117 correct &= check_delete_on_close(cli2, -1, fname, False, __location__);
1119 /* Now try opening again for read-only. */
1120 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
1121 SEC_RIGHTS_FILE_READ,
1122 FILE_ATTRIBUTE_NORMAL,
1123 NTCREATEX_SHARE_ACCESS_READ|
1124 NTCREATEX_SHARE_ACCESS_WRITE|
1125 NTCREATEX_SHARE_ACCESS_DELETE,
1126 NTCREATEX_DISP_OPEN,
1127 0, 0);
1130 /* Should work. */
1131 if (fnum2 == -1) {
1132 printf("(%s) open - 1 of %s failed (%s)\n",
1133 __location__, fname, smbcli_errstr(cli1->tree));
1134 correct = False;
1135 goto fail;
1138 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
1139 correct &= check_delete_on_close(cli1, -1, fname, False, __location__);
1140 correct &= check_delete_on_close(cli2, fnum2, fname, False, __location__);
1141 correct &= check_delete_on_close(cli2, -1, fname, False, __location__);
1143 smbcli_close(cli1->tree, fnum1);
1145 correct &= check_delete_on_close(cli2, fnum2, fname, True, __location__);
1146 correct &= check_delete_on_close(cli2, -1, fname, True, __location__);
1148 smbcli_close(cli2->tree, fnum2);
1150 /* And the file should be deleted ! */
1151 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1152 if (fnum1 != -1) {
1153 printf("(%s) open of %s succeeded (should fail)\n",
1154 __location__, fname);
1155 correct = False;
1156 goto fail;
1159 printf("sixteenth delete on close test succeeded.\n");
1161 fail:
1163 return correct;
1166 /* Test 17 ... */
1167 static BOOL deltest17(struct smbcli_state *cli1, struct smbcli_state *cli2)
1169 int fnum1 = -1;
1170 int fnum2 = -1;
1171 BOOL correct = True;
1173 del_clean_area(cli1, cli2);
1175 /* Test 17. */
1177 /* Ensure the file doesn't already exist. */
1178 smbcli_close(cli1->tree, fnum1);
1179 smbcli_close(cli1->tree, fnum2);
1180 smbcli_setatr(cli1->tree, fname, 0, 0);
1181 smbcli_unlink(cli1->tree, fname);
1183 /* Firstly open and create with all access */
1184 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1185 SEC_RIGHTS_FILE_ALL,
1186 FILE_ATTRIBUTE_NORMAL,
1187 NTCREATEX_SHARE_ACCESS_READ|
1188 NTCREATEX_SHARE_ACCESS_WRITE|
1189 NTCREATEX_SHARE_ACCESS_DELETE,
1190 NTCREATEX_DISP_CREATE,
1191 0, 0);
1192 if (fnum1 == -1) {
1193 printf("(%s) open - 1 of %s failed (%s)\n",
1194 __location__, fname, smbcli_errstr(cli1->tree));
1195 correct = False;
1196 goto fail;
1199 /* And close - just to create the file. */
1200 smbcli_close(cli1->tree, fnum1);
1202 /* Next open with all access, but add delete on close. */
1203 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1204 SEC_RIGHTS_FILE_ALL,
1205 FILE_ATTRIBUTE_NORMAL,
1206 NTCREATEX_SHARE_ACCESS_READ|
1207 NTCREATEX_SHARE_ACCESS_WRITE|
1208 NTCREATEX_SHARE_ACCESS_DELETE,
1209 NTCREATEX_DISP_OPEN,
1210 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1212 if (fnum1 == -1) {
1213 printf("(%s) open - 1 of %s failed (%s)\n",
1214 __location__, fname, smbcli_errstr(cli1->tree));
1215 correct = False;
1216 goto fail;
1219 /* The delete on close bit is *not* reported as being set. */
1220 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
1222 /* Now try opening again for read-only. */
1223 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1224 SEC_RIGHTS_FILE_READ|
1225 SEC_STD_DELETE,
1226 FILE_ATTRIBUTE_NORMAL,
1227 NTCREATEX_SHARE_ACCESS_READ|
1228 NTCREATEX_SHARE_ACCESS_WRITE|
1229 NTCREATEX_SHARE_ACCESS_DELETE,
1230 NTCREATEX_DISP_OPEN,
1231 0, 0);
1233 /* Should work. */
1234 if (fnum2 == -1) {
1235 printf("(%s) open - 1 of %s failed (%s)\n",
1236 __location__, fname, smbcli_errstr(cli1->tree));
1237 correct = False;
1238 goto fail;
1241 /* still not reported as being set on either */
1242 correct &= check_delete_on_close(cli1, fnum1, fname, False, __location__);
1243 correct &= check_delete_on_close(cli1, fnum2, fname, False, __location__);
1245 smbcli_close(cli1->tree, fnum1);
1247 correct &= check_delete_on_close(cli1, fnum2, fname, False, __location__);
1249 smbcli_close(cli1->tree, fnum2);
1251 /* See if the file is deleted - shouldn't be.... */
1252 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1253 if (fnum1 == -1) {
1254 printf("(%s) open of %s failed (should succeed) - %s\n",
1255 __location__, fname, smbcli_errstr(cli1->tree));
1256 correct = False;
1257 goto fail;
1260 printf("seventeenth delete on close test succeeded.\n");
1262 fail:
1264 return correct;
1267 /* Test 18 ... */
1268 static BOOL deltest18(struct smbcli_state *cli1, struct smbcli_state *cli2)
1270 int fnum1 = -1;
1271 int fnum2 = -1;
1272 BOOL correct = True;
1274 del_clean_area(cli1, cli2);
1276 /* Test 18. With directories. */
1278 /* Ensure the file doesn't already exist. */
1279 smbcli_close(cli1->tree, fnum1);
1280 smbcli_close(cli1->tree, fnum2);
1282 smbcli_deltree(cli1->tree, dname);
1284 /* Firstly create with all access, but delete on close. */
1285 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1286 SEC_FILE_READ_DATA|
1287 SEC_FILE_WRITE_DATA|
1288 SEC_STD_DELETE,
1289 FILE_ATTRIBUTE_DIRECTORY,
1290 NTCREATEX_SHARE_ACCESS_READ|
1291 NTCREATEX_SHARE_ACCESS_WRITE|
1292 NTCREATEX_SHARE_ACCESS_DELETE,
1293 NTCREATEX_DISP_CREATE,
1294 NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1296 if (fnum1 == -1) {
1297 printf("(%s) open - 1 of %s failed (%s)\n",
1298 __location__, dname, smbcli_errstr(cli1->tree));
1299 correct = False;
1300 goto fail;
1303 /* The delete on close bit is *not* reported as being set. */
1304 correct &= check_delete_on_close(cli1, fnum1, dname, False, __location__);
1306 /* Now try opening again for read-only. */
1307 fnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
1308 SEC_RIGHTS_FILE_READ,
1309 FILE_ATTRIBUTE_DIRECTORY,
1310 NTCREATEX_SHARE_ACCESS_READ|
1311 NTCREATEX_SHARE_ACCESS_WRITE|
1312 NTCREATEX_SHARE_ACCESS_DELETE,
1313 NTCREATEX_DISP_OPEN,
1314 NTCREATEX_OPTIONS_DIRECTORY, 0);
1317 /* Should work. */
1318 if (fnum2 == -1) {
1319 printf("(%s) open - 1 of %s failed (%s)\n",
1320 __location__, dname, smbcli_errstr(cli1->tree));
1321 correct = False;
1322 goto fail;
1325 correct &= check_delete_on_close(cli1, fnum1, dname, False, __location__);
1326 correct &= check_delete_on_close(cli1, fnum2, dname, False, __location__);
1328 smbcli_close(cli1->tree, fnum1);
1330 correct &= check_delete_on_close(cli1, fnum2, dname, True, __location__);
1332 smbcli_close(cli1->tree, fnum2);
1334 /* And the directory should be deleted ! */
1335 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1336 SEC_RIGHTS_FILE_READ,
1337 FILE_ATTRIBUTE_DIRECTORY,
1338 NTCREATEX_SHARE_ACCESS_READ|
1339 NTCREATEX_SHARE_ACCESS_WRITE|
1340 NTCREATEX_SHARE_ACCESS_DELETE,
1341 NTCREATEX_DISP_OPEN,
1342 NTCREATEX_OPTIONS_DIRECTORY, 0);
1343 if (fnum1 != -1) {
1344 printf("(%s) open of %s succeeded (should fail)\n",
1345 __location__, dname);
1346 correct = False;
1347 goto fail;
1350 printf("eighteenth delete on close test succeeded.\n");
1352 fail:
1354 return correct;
1357 /* Test 19 ... */
1358 static BOOL deltest19(struct smbcli_state *cli1, struct smbcli_state *cli2)
1360 int fnum1 = -1;
1361 int fnum2 = -1;
1362 BOOL correct = True;
1364 del_clean_area(cli1, cli2);
1366 /* Test 19. */
1368 smbcli_deltree(cli1->tree, dname);
1370 /* Firstly open and create with all access */
1371 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1372 SEC_FILE_READ_DATA|
1373 SEC_FILE_WRITE_DATA|
1374 SEC_STD_DELETE,
1375 FILE_ATTRIBUTE_DIRECTORY,
1376 NTCREATEX_SHARE_ACCESS_READ|
1377 NTCREATEX_SHARE_ACCESS_WRITE|
1378 NTCREATEX_SHARE_ACCESS_DELETE,
1379 NTCREATEX_DISP_CREATE,
1380 NTCREATEX_OPTIONS_DIRECTORY, 0);
1382 if (fnum1 == -1) {
1383 printf("(%s) open - 1 of %s failed (%s)\n",
1384 __location__, dname, smbcli_errstr(cli1->tree));
1385 correct = False;
1386 goto fail;
1389 /* And close - just to create the directory. */
1390 smbcli_close(cli1->tree, fnum1);
1392 /* Next open with all access, but add delete on close. */
1393 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1394 SEC_FILE_READ_DATA|
1395 SEC_FILE_WRITE_DATA|
1396 SEC_STD_DELETE,
1397 FILE_ATTRIBUTE_DIRECTORY,
1398 NTCREATEX_SHARE_ACCESS_READ|
1399 NTCREATEX_SHARE_ACCESS_WRITE|
1400 NTCREATEX_SHARE_ACCESS_DELETE,
1401 NTCREATEX_DISP_OPEN,
1402 NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1404 if (fnum1 == -1) {
1405 printf("(%s) open - 1 of %s failed (%s)\n",
1406 __location__, fname, smbcli_errstr(cli1->tree));
1407 correct = False;
1408 goto fail;
1411 /* The delete on close bit is *not* reported as being set. */
1412 correct &= check_delete_on_close(cli1, fnum1, dname, False, __location__);
1414 /* Now try opening again for read-only. */
1415 fnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
1416 SEC_RIGHTS_FILE_READ,
1417 FILE_ATTRIBUTE_DIRECTORY,
1418 NTCREATEX_SHARE_ACCESS_READ|
1419 NTCREATEX_SHARE_ACCESS_WRITE|
1420 NTCREATEX_SHARE_ACCESS_DELETE,
1421 NTCREATEX_DISP_OPEN,
1422 NTCREATEX_OPTIONS_DIRECTORY, 0);
1424 /* Should work. */
1425 if (fnum2 == -1) {
1426 printf("(%s) open - 1 of %s failed (%s)\n",
1427 __location__, dname, smbcli_errstr(cli1->tree));
1428 correct = False;
1429 goto fail;
1432 smbcli_close(cli1->tree, fnum1);
1434 correct &= check_delete_on_close(cli1, fnum2, dname, True, __location__);
1436 smbcli_close(cli1->tree, fnum2);
1438 /* See if the file is deleted - for a directory this seems to be true ! */
1439 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1440 SEC_RIGHTS_FILE_READ,
1441 FILE_ATTRIBUTE_DIRECTORY,
1442 NTCREATEX_SHARE_ACCESS_READ|
1443 NTCREATEX_SHARE_ACCESS_WRITE|
1444 NTCREATEX_SHARE_ACCESS_DELETE,
1445 NTCREATEX_DISP_OPEN,
1446 NTCREATEX_OPTIONS_DIRECTORY, 0);
1448 CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1450 if (fnum1 != -1) {
1451 printf("(%s) open of %s succeeded (should fail)\n",
1452 __location__, dname);
1453 correct = False;
1454 goto fail;
1457 printf("nineteenth delete on close test succeeded.\n");
1459 fail:
1461 return correct;
1464 /* Test 20 ... */
1465 static BOOL deltest20(struct smbcli_state *cli1, struct smbcli_state *cli2)
1467 int fnum1 = -1;
1468 int dnum1 = -1;
1469 BOOL correct = True;
1470 NTSTATUS status;
1472 del_clean_area(cli1, cli2);
1474 /* Test 20 -- non-empty directory hardest to get right... */
1476 smbcli_deltree(cli1->tree, dname);
1478 dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
1479 SEC_FILE_READ_DATA|
1480 SEC_FILE_WRITE_DATA|
1481 SEC_STD_DELETE,
1482 FILE_ATTRIBUTE_DIRECTORY,
1483 NTCREATEX_SHARE_ACCESS_READ|
1484 NTCREATEX_SHARE_ACCESS_WRITE|
1485 NTCREATEX_SHARE_ACCESS_DELETE,
1486 NTCREATEX_DISP_CREATE,
1487 NTCREATEX_OPTIONS_DIRECTORY, 0);
1488 if (dnum1 == -1) {
1489 printf("(%s) open of %s failed: %s!\n",
1490 __location__, dname, smbcli_errstr(cli1->tree));
1491 correct = False;
1492 goto fail;
1495 correct &= check_delete_on_close(cli1, dnum1, dname, False, __location__);
1496 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1499 char *fullname;
1500 asprintf(&fullname, "\\%s%s", dname, fname);
1501 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1502 DENY_NONE);
1503 if (fnum1 != -1) {
1504 printf("(%s) smbcli_open succeeded, should have "
1505 "failed with NT_STATUS_DELETE_PENDING\n",
1506 __location__);
1507 correct = False;
1508 goto fail;
1511 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree),
1512 NT_STATUS_DELETE_PENDING)) {
1513 printf("(%s) smbcli_open returned %s, expected "
1514 "NT_STATUS_DELETE_PENDING\n",
1515 __location__, smbcli_errstr(cli1->tree));
1516 correct = False;
1517 goto fail;
1521 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, False);
1522 if (!NT_STATUS_IS_OK(status)) {
1523 printf("(%s) setting delete_on_close on file failed !\n",
1524 __location__);
1525 correct = False;
1526 goto fail;
1530 char *fullname;
1531 asprintf(&fullname, "\\%s%s", dname, fname);
1532 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1533 DENY_NONE);
1534 if (fnum1 == -1) {
1535 printf("(%s) smbcli_open failed: %s\n",
1536 __location__, smbcli_errstr(cli1->tree));
1537 correct = False;
1538 goto fail;
1540 smbcli_close(cli1->tree, fnum1);
1543 status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1545 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1546 printf("(%s) setting delete_on_close returned %s, expected "
1547 "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__,
1548 smbcli_errstr(cli1->tree));
1549 correct = False;
1550 goto fail;
1553 smbcli_close(cli1->tree, dnum1);
1555 printf("twentieth delete on close test succeeded.\n");
1557 fail:
1559 return correct;
1562 /* Test 21 ... */
1563 static BOOL deltest21(struct smbcli_state **ppcli1, struct smbcli_state **ppcli2)
1565 int fnum1 = -1;
1566 struct smbcli_state *cli1 = *ppcli1;
1567 struct smbcli_state *cli2 = *ppcli2;
1568 BOOL correct = True;
1570 del_clean_area(cli1, cli2);
1572 /* Test 21 -- Test removal of file after socket close. */
1574 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1575 SEC_RIGHTS_FILE_ALL,
1576 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1577 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1579 if (fnum1 == -1) {
1580 printf("(%s) open of %s failed (%s)\n",
1581 __location__, fname, smbcli_errstr(cli1->tree));
1582 return False;
1585 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
1586 printf("(%s) setting delete_on_close failed (%s)\n",
1587 __location__, smbcli_errstr(cli1->tree));
1588 return False;
1591 /* Ensure delete on close is set. */
1592 correct &= check_delete_on_close(cli1, fnum1, fname, True, __location__);
1594 /* Now yank the rug from under cli1. */
1595 smbcli_transport_dead(cli1->transport, NT_STATUS_LOCAL_DISCONNECT);
1597 fnum1 = -1;
1599 if (!torture_open_connection(ppcli1, 0)) {
1600 return False;
1603 cli1 = *ppcli1;
1605 /* On slow build farm machines it might happen that they are not fast
1606 * enogh to delete the file for this test */
1607 msleep(200);
1609 /* File should not be there. */
1610 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1611 SEC_RIGHTS_FILE_READ,
1612 FILE_ATTRIBUTE_NORMAL,
1613 NTCREATEX_SHARE_ACCESS_READ|
1614 NTCREATEX_SHARE_ACCESS_WRITE|
1615 NTCREATEX_SHARE_ACCESS_DELETE,
1616 NTCREATEX_DISP_OPEN,
1617 0, 0);
1619 CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1621 printf("twenty-first delete on close test succeeded.\n");
1623 fail:
1625 return correct;
1629 Test delete on close semantics.
1631 BOOL torture_test_delete(struct torture_context *torture)
1633 struct smbcli_state *cli1 = NULL;
1634 struct smbcli_state *cli2 = NULL;
1635 BOOL correct = True;
1637 printf("starting delete test\n");
1639 if (!torture_open_connection(&cli1, 0)) {
1640 return False;
1643 if (!torture_open_connection(&cli2, 1)) {
1644 printf("(%s) failed to open second connection.\n",
1645 __location__);
1646 correct = False;
1647 goto fail;
1650 correct &= deltest1(cli1, cli2);
1651 correct &= deltest2(cli1, cli2);
1652 correct &= deltest3(cli1, cli2);
1653 correct &= deltest4(cli1, cli2);
1654 correct &= deltest5(cli1, cli2);
1655 correct &= deltest6(cli1, cli2);
1656 correct &= deltest7(cli1, cli2);
1657 correct &= deltest8(cli1, cli2);
1658 correct &= deltest9(cli1, cli2);
1659 correct &= deltest10(cli1, cli2);
1660 correct &= deltest11(cli1, cli2);
1661 correct &= deltest12(cli1, cli2);
1662 correct &= deltest13(cli1, cli2);
1663 correct &= deltest14(cli1, cli2);
1664 correct &= deltest15(cli1, cli2);
1665 if (!lp_parm_bool(-1, "target", "samba3", False)) {
1666 correct &= deltest16(cli1, cli2);
1667 correct &= deltest17(cli1, cli2);
1668 correct &= deltest18(cli1, cli2);
1669 correct &= deltest19(cli1, cli2);
1670 correct &= deltest20(cli1, cli2);
1672 correct &= deltest21(&cli1, &cli2);
1674 if (!correct) {
1675 printf("Failed delete test\n");
1676 } else {
1677 printf("delete test ok !\n");
1680 fail:
1681 del_clean_area(cli1, cli2);
1683 if (!torture_close_connection(cli1)) {
1684 correct = False;
1686 if (!torture_close_connection(cli2)) {
1687 correct = False;
1689 return correct;