226e5a5aa485cb350fac8eddbfce9685ce57bd24
[samba.git] / source / torture / basic / delete.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    delete on close testing
5
6    Copyright (C) Andrew Tridgell 2003
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "libcli/libcli.h"
25 #include "torture/torture.h"
26 #include "system/filesys.h"
27 #include "libcli/raw/libcliraw.h"
28
29 #include "torture/raw/proto.h"
30
31 static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
32                                   const char *fname, BOOL expect_it)
33 {
34         TALLOC_CTX *mem_ctx = talloc_init("single_search");
35         union smb_search_data data;
36         NTSTATUS status;
37
38         time_t c_time, a_time, m_time;
39         size_t size;
40         uint16_t mode;
41
42         BOOL res = True;
43
44         status = torture_single_search(cli, mem_ctx,
45                                        fname, RAW_SEARCH_FULL_DIRECTORY_INFO,
46                                        FILE_ATTRIBUTE_DIRECTORY,
47                                        &data);
48         if (!NT_STATUS_IS_OK(status)) {
49                 printf("(%s) single_search failed (%s)\n", 
50                        __location__, nt_errstr(status));
51                 res = False;
52                 goto done;
53         }
54
55         if (fnum != -1) {
56                 union smb_fileinfo io;
57                 int nlink = expect_it ? 0 : 1;
58
59                 io.all_info.level = RAW_FILEINFO_ALL_INFO;
60                 io.all_info.in.fnum = fnum;
61
62                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
63                 if (!NT_STATUS_IS_OK(status)) {
64                         printf("(%s) qpathinfo failed (%s)\n", __location__,
65                                nt_errstr(status));
66                         res = False;
67                         goto done;
68                 }
69
70                 if (expect_it != io.all_info.out.delete_pending) {
71                         printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
72                                expect_it, io.all_info.out.delete_pending);
73                         res = False;
74                         goto done;
75                 }
76
77                 if (nlink != io.all_info.out.nlink) {
78                         printf("Expected nlink %d, qfileinfo gave %d\n",
79                                nlink, io.all_info.out.nlink);
80                         res = False;
81                         goto done;
82                 }
83
84                 io.standard_info.level = RAW_FILEINFO_STANDARD_INFO;
85                 io.standard_info.in.fnum = fnum;
86
87                 status = smb_raw_fileinfo(cli->tree, mem_ctx, &io);
88                 if (!NT_STATUS_IS_OK(status)) {
89                         printf("(%s) qpathinfo failed (%s)\n", __location__,
90                                nt_errstr(status));
91                         res = False;
92                         goto done;
93                 }
94
95                 if (expect_it != io.standard_info.out.delete_pending) {
96                         printf("Expected del_on_close flag %d, qfileinfo gave %d\n",
97                                expect_it, io.standard_info.out.delete_pending);
98                         res = False;
99                         goto done;
100                 }
101
102                 if (nlink != io.standard_info.out.nlink) {
103                         printf("Expected nlink %d, qfileinfo gave %d\n",
104                                nlink, io.all_info.out.nlink);
105                         res = False;
106                         goto done;
107                 }
108
109         }
110
111         status = smbcli_qpathinfo(cli->tree, fname,
112                                   &c_time, &a_time, &m_time,
113                                   &size, &mode);
114
115         if (expect_it) {
116                 if (!NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
117                         printf("(%s) qpathinfo did not give correct error "
118                                "code (%s) -- NT_STATUS_DELETE_PENDING "
119                                "expected\n", __location__,
120                                nt_errstr(status));
121                         res = False;
122                         goto done;
123                 }
124         } else {
125                 if (!NT_STATUS_IS_OK(status)) {
126                         printf("(%s) qpathinfo failed (%s)\n", __location__,
127                                nt_errstr(status));
128                         res = False;
129                         goto done;
130                 }
131         }
132
133  done:
134         talloc_free(mem_ctx);
135         return res;
136 }
137
138 #define CHECK_STATUS(_cli, _expected) do { \
139         if (!NT_STATUS_EQUAL(_cli->tree->session->transport->error.e.nt_status, _expected)) { \
140                 printf("(%d) Incorrect status %s - should be %s\n", \
141                        __LINE__, nt_errstr(_cli->tree->session->transport->error.e.nt_status), nt_errstr(_expected)); \
142                 correct = False; \
143                 goto fail; \
144         }} while (0)
145
146 const char *fname = "\\delete.file";
147 const char *fname_new = "\\delete.new";
148 const char *dirname = "\\delete.dir";
149
150 static void del_clean_area(struct smbcli_state *cli1, struct smbcli_state *cli2)
151 {
152         smbcli_deltree(cli1->tree, dirname);
153         smbcli_setatr(cli1->tree, fname, 0, 0);
154         smbcli_unlink(cli1->tree, fname);
155         smbcli_setatr(cli1->tree, fname_new, 0, 0);
156         smbcli_unlink(cli1->tree, fname_new);
157
158         smb_raw_exit(cli1->session);
159         smb_raw_exit(cli2->session);
160 }
161
162 /* Test 1 - this should delete the file on close. */
163
164 static BOOL deltest1(struct smbcli_state *cli1, struct smbcli_state *cli2)
165 {
166         int fnum1 = -1;
167
168         del_clean_area(cli1, cli2);
169
170         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
171                                       SEC_RIGHTS_FILE_ALL,
172                                       FILE_ATTRIBUTE_NORMAL,
173                                       NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 
174                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
175         
176         if (fnum1 == -1) {
177                 printf("(%s) open of %s failed (%s)\n", 
178                        __location__, fname, smbcli_errstr(cli1->tree));
179                 return False;
180         }
181         
182         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
183                 printf("(%s) close failed (%s)\n", 
184                        __location__, smbcli_errstr(cli1->tree));
185                 return False;
186         }
187
188         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
189         if (fnum1 != -1) {
190                 printf("(%s) open of %s succeeded (should fail)\n", 
191                        __location__, fname);
192                 return False;
193         }
194         
195         printf("first delete on close test succeeded.\n");
196         return True;
197 }
198
199 /* Test 2 - this should delete the file on close. */
200 static BOOL deltest2(struct smbcli_state *cli1, struct smbcli_state *cli2)
201 {
202         int fnum1 = -1;
203
204         del_clean_area(cli1, cli2);
205
206         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
207                                       SEC_RIGHTS_FILE_ALL,
208                                       FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, 
209                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
210         
211         if (fnum1 == -1) {
212                 printf("(%s) open of %s failed (%s)\n", 
213                        __location__, fname, smbcli_errstr(cli1->tree));
214                 return False;
215         }
216         
217         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
218                 printf("(%s) setting delete_on_close failed (%s)\n", 
219                        __location__, smbcli_errstr(cli1->tree));
220                 return False;
221         }
222         
223         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
224                 printf("(%s) close failed (%s)\n", 
225                        __location__, smbcli_errstr(cli1->tree));
226                 return False;
227         }
228         
229         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
230         if (fnum1 != -1) {
231                 printf("(%s) open of %s succeeded should have been deleted on close !\n", 
232                        __location__, fname);
233                 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
234                         printf("(%s) close failed (%s)\n", 
235                                __location__, smbcli_errstr(cli1->tree));
236                         return False;
237                 }
238                 smbcli_unlink(cli1->tree, fname);
239         } else {
240                 printf("second delete on close test succeeded.\n");
241         }
242         return True;
243 }
244
245 /* Test 3 - ... */
246 static BOOL deltest3(struct smbcli_state *cli1, struct smbcli_state *cli2)
247 {
248         int fnum1 = -1;
249         int fnum2 = -1;
250
251         del_clean_area(cli1, cli2);
252
253         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
254                                       SEC_RIGHTS_FILE_ALL,
255                                       FILE_ATTRIBUTE_NORMAL,
256                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
257                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
258
259         if (fnum1 == -1) {
260                 printf("(%s) open - 1 of %s failed (%s)\n", 
261                        __location__, fname, smbcli_errstr(cli1->tree));
262                 return False;
263         }
264
265         /* This should fail with a sharing violation - open for delete is only compatible
266            with SHARE_DELETE. */
267
268         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
269                                       SEC_RIGHTS_FILE_READ, 
270                                       FILE_ATTRIBUTE_NORMAL,
271                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
272                                       NTCREATEX_DISP_OPEN, 0, 0);
273
274         if (fnum2 != -1) {
275                 printf("(%s) open  - 2 of %s succeeded - should have failed.\n", 
276                        __location__, fname);
277                 return False;
278         }
279
280         /* This should succeed. */
281
282         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
283                                       SEC_RIGHTS_FILE_READ, 
284                                       FILE_ATTRIBUTE_NORMAL,
285                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, 
286                                       NTCREATEX_DISP_OPEN, 0, 0);
287
288         if (fnum2 == -1) {
289                 printf("(%s) open  - 2 of %s failed (%s)\n", 
290                        __location__, fname, smbcli_errstr(cli1->tree));
291                 return False;
292         }
293
294         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
295                 printf("(%s) setting delete_on_close failed (%s)\n", 
296                        __location__, smbcli_errstr(cli1->tree));
297                 return False;
298         }
299         
300         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
301                 printf("(%s) close 1 failed (%s)\n", 
302                        __location__, smbcli_errstr(cli1->tree));
303                 return False;
304         }
305         
306         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
307                 printf("(%s) close 2 failed (%s)\n", 
308                        __location__, smbcli_errstr(cli1->tree));
309                 return False;
310         }
311         
312         /* This should fail - file should no longer be there. */
313
314         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
315         if (fnum1 != -1) {
316                 printf("(%s) open of %s succeeded should have been deleted on close !\n", 
317                        __location__, fname);
318                 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
319                         printf("(%s) close failed (%s)\n", 
320                                __location__, smbcli_errstr(cli1->tree));
321                 }
322                 smbcli_unlink(cli1->tree, fname);
323                 return False;
324         } else {
325                 printf("third delete on close test succeeded.\n");
326         }
327         return True;
328 }
329
330 /* Test 4 ... */
331 static BOOL deltest4(struct smbcli_state *cli1, struct smbcli_state *cli2)
332 {
333         int fnum1 = -1;
334         int fnum2 = -1;
335         BOOL correct = True;
336
337         del_clean_area(cli1, cli2);
338
339         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
340                                       SEC_FILE_READ_DATA  | 
341                                       SEC_FILE_WRITE_DATA |
342                                       SEC_STD_DELETE,
343                                       FILE_ATTRIBUTE_NORMAL, 
344                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, 
345                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
346                                                                 
347         if (fnum1 == -1) {
348                 printf("(%s) open of %s failed (%s)\n", 
349                        __location__, fname, smbcli_errstr(cli1->tree));
350                 return False;
351         }
352
353         /* This should succeed. */
354         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
355                                       SEC_RIGHTS_FILE_READ,
356                                       FILE_ATTRIBUTE_NORMAL, 
357                                       NTCREATEX_SHARE_ACCESS_READ  | 
358                                       NTCREATEX_SHARE_ACCESS_WRITE |
359                                       NTCREATEX_SHARE_ACCESS_DELETE, 
360                                       NTCREATEX_DISP_OPEN, 0, 0);
361         if (fnum2 == -1) {
362                 printf("(%s) open  - 2 of %s failed (%s)\n", 
363                        __location__, fname, smbcli_errstr(cli1->tree));
364                 return False;
365         }
366         
367         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
368                 printf("(%s) close - 1 failed (%s)\n", 
369                        __location__, smbcli_errstr(cli1->tree));
370                 return False;
371         }
372         
373         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
374                 printf("(%s) setting delete_on_close failed (%s)\n", 
375                        __location__, smbcli_errstr(cli1->tree));
376                 return False;
377         }
378         
379         /* This should fail - no more opens once delete on close set. */
380         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
381                                       SEC_RIGHTS_FILE_READ,
382                                       FILE_ATTRIBUTE_NORMAL, 
383                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
384                                       NTCREATEX_DISP_OPEN, 0, 0);
385         if (fnum2 != -1) {
386                 printf("(%s) open  - 3 of %s succeeded ! Should have failed.\n",
387                        __location__, fname );
388                 return False;
389         }
390         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
391
392         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
393                 printf("(%s) close - 2 failed (%s)\n", 
394                        __location__, smbcli_errstr(cli1->tree));
395                 return False;
396         }
397         
398         printf("fourth delete on close test succeeded.\n");
399
400   fail:
401
402         return correct;
403 }
404
405 /* Test 5 ... */
406 static BOOL deltest5(struct smbcli_state *cli1, struct smbcli_state *cli2)
407 {
408         int fnum1 = -1;
409
410         del_clean_area(cli1, cli2);
411
412         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
413         if (fnum1 == -1) {
414                 printf("(%s) open of %s failed (%s)\n", 
415                        __location__, fname, smbcli_errstr(cli1->tree));
416                 return False;
417         }
418
419         /* This should fail - only allowed on NT opens with DELETE access. */
420
421         if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
422                 printf("(%s) setting delete_on_close on OpenX file succeeded - should fail !\n",
423                        __location__);
424                 return False;
425         }
426
427         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
428                 printf("(%s) close - 2 failed (%s)\n", 
429                        __location__, smbcli_errstr(cli1->tree));
430                 return False;
431         }
432
433         printf("fifth delete on close test succeeded.\n");
434         return True;
435 }
436
437 /* Test 6 ... */
438 static BOOL deltest6(struct smbcli_state *cli1, struct smbcli_state *cli2)
439 {
440         int fnum1 = -1;
441
442         del_clean_area(cli1, cli2);
443
444         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
445                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
446                                    FILE_ATTRIBUTE_NORMAL, 
447                                    NTCREATEX_SHARE_ACCESS_READ  |
448                                    NTCREATEX_SHARE_ACCESS_WRITE |
449                                    NTCREATEX_SHARE_ACCESS_DELETE,
450                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
451         
452         if (fnum1 == -1) {
453                 printf("(%s) open of %s failed (%s)\n", 
454                        __location__, fname, smbcli_errstr(cli1->tree));
455                 return False;
456         }
457         
458         /* This should fail - only allowed on NT opens with DELETE access. */
459         
460         if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
461                 printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
462                        __location__);
463                 return False;
464         }
465
466         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
467                 printf("(%s) close - 2 failed (%s)\n", 
468                        __location__, smbcli_errstr(cli1->tree));
469                 return False;
470         }
471
472         printf("sixth delete on close test succeeded.\n");
473         return True;
474 }
475
476 /* Test 7 ... */
477 static BOOL deltest7(struct smbcli_state *cli1, struct smbcli_state *cli2)
478 {
479         int fnum1 = -1;
480         BOOL correct = True;
481
482         del_clean_area(cli1, cli2);
483
484         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
485                                       SEC_FILE_READ_DATA  | 
486                                       SEC_FILE_WRITE_DATA |
487                                       SEC_STD_DELETE,
488                                       FILE_ATTRIBUTE_NORMAL, 0, 
489                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
490                                                                 
491         if (fnum1 == -1) {
492                 printf("(%s) open of %s failed (%s)\n", 
493                        __location__, fname, smbcli_errstr(cli1->tree));
494                 correct = False;
495                 goto fail;
496         }
497
498         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
499                 printf("(%s) setting delete_on_close on file failed !\n",
500                        __location__);
501                 correct = False;
502                 goto fail;
503         }
504
505         correct &= check_delete_on_close(cli1, fnum1, fname, True);
506         
507         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
508                 printf("(%s) unsetting delete_on_close on file failed !\n",
509                        __location__);
510                 correct = False;
511                 goto fail;
512         }
513
514         correct &= check_delete_on_close(cli1, fnum1, fname, False);
515         
516         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
517                 printf("(%s) close - 2 failed (%s)\n", 
518                        __location__, smbcli_errstr(cli1->tree));
519                 correct = False;
520                 goto fail;
521         }
522         
523         /* This next open should succeed - we reset the flag. */
524         
525         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
526         if (fnum1 == -1) {
527                 printf("(%s) open of %s failed (%s)\n", 
528                        __location__, fname, smbcli_errstr(cli1->tree));
529                 correct = False;
530                 goto fail;
531         }
532
533         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
534                 printf("(%s) close - 2 failed (%s)\n", 
535                        __location__, smbcli_errstr(cli1->tree));
536                 correct = False;
537                 goto fail;
538         }
539
540         printf("seventh delete on close test succeeded.\n");
541
542   fail:
543
544         return correct;
545 }
546
547 /* Test 8 ... */
548 static BOOL deltest8(struct smbcli_state *cli1, struct smbcli_state *cli2)
549 {
550         int fnum1 = -1;
551         int fnum2 = -1;
552         BOOL correct = True;
553
554         del_clean_area(cli1, cli2);
555
556         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
557                                       SEC_FILE_READ_DATA|
558                                       SEC_FILE_WRITE_DATA|
559                                       SEC_STD_DELETE,
560                                       FILE_ATTRIBUTE_NORMAL, 
561                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
562                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
563         
564         if (fnum1 == -1) {
565                 printf("(%s) open of %s failed (%s)\n", 
566                        __location__, fname, smbcli_errstr(cli1->tree));
567                 correct = False;
568                 goto fail;
569         }
570
571         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, 
572                                       SEC_FILE_READ_DATA|
573                                       SEC_FILE_WRITE_DATA|
574                                       SEC_STD_DELETE,
575                                       FILE_ATTRIBUTE_NORMAL, 
576                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
577                                       NTCREATEX_DISP_OPEN, 0, 0);
578         
579         if (fnum2 == -1) {
580                 printf("(%s) open of %s failed (%s)\n", 
581                        __location__, fname, smbcli_errstr(cli1->tree));
582                 correct = False;
583                 goto fail;
584         }
585
586         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
587                 printf("(%s) setting delete_on_close on file failed !\n",
588                        __location__);
589                 correct = False;
590                 goto fail;
591         }
592
593         correct &= check_delete_on_close(cli1, fnum1, fname, True);
594         correct &= check_delete_on_close(cli2, fnum2, fname, True);
595
596         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
597                 printf("(%s) close - 1 failed (%s)\n", 
598                        __location__, smbcli_errstr(cli1->tree));
599                 correct = False;
600                 goto fail;
601         }
602
603         correct &= check_delete_on_close(cli1, -1, fname, True);
604         correct &= check_delete_on_close(cli2, fnum2, fname, True);
605         
606         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
607                 printf("(%s) close - 2 failed (%s)\n", 
608                        __location__, smbcli_errstr(cli2->tree));
609                 correct = False;
610                 goto fail;
611         }
612
613         /* This should fail.. */
614         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
615         if (fnum1 != -1) {
616                 printf("(%s) open of %s succeeded should have been deleted on close !\n",
617                        __location__, fname);
618                 correct = False;
619         } else {
620                 printf("eighth delete on close test succeeded.\n");
621         }
622
623   fail:
624
625         return correct;
626 }
627
628 /* Test 9 ... */
629 static BOOL deltest9(struct smbcli_state *cli1, struct smbcli_state *cli2)
630 {
631         int fnum1 = -1;
632
633         del_clean_area(cli1, cli2);
634
635         /* This should fail - we need to set DELETE_ACCESS. */
636         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
637                                       SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
638                                       FILE_ATTRIBUTE_NORMAL, 
639                                       NTCREATEX_SHARE_ACCESS_NONE, 
640                                       NTCREATEX_DISP_OVERWRITE_IF, 
641                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
642         
643         if (fnum1 != -1) {
644                 printf("(%s) open of %s succeeded should have failed!\n", 
645                        __location__, fname);
646                 return False;
647         }
648
649         printf("ninth delete on close test succeeded.\n");
650         return True;
651 }
652
653 /* Test 10 ... */
654 static BOOL deltest10(struct smbcli_state *cli1, struct smbcli_state *cli2)
655 {
656         int fnum1 = -1;
657         BOOL correct = True;
658
659         del_clean_area(cli1, cli2);
660
661         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
662                                       SEC_FILE_READ_DATA|
663                                       SEC_FILE_WRITE_DATA|
664                                       SEC_STD_DELETE,
665                                       FILE_ATTRIBUTE_NORMAL, 
666                                       NTCREATEX_SHARE_ACCESS_NONE, 
667                                       NTCREATEX_DISP_OVERWRITE_IF, 
668                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
669         if (fnum1 == -1) {
670                 printf("(%s) open of %s failed (%s)\n", 
671                        __location__, fname, smbcli_errstr(cli1->tree));
672                 correct = False;
673                 goto fail;
674         }
675
676         /* This should delete the file. */
677         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
678                 printf("(%s) close failed (%s)\n", 
679                        __location__, smbcli_errstr(cli1->tree));
680                 correct = False;
681                 goto fail;
682         }
683
684         /* This should fail.. */
685         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
686         if (fnum1 != -1) {
687                 printf("(%s) open of %s succeeded should have been deleted on close !\n",
688                        __location__, fname);
689                 correct = False;
690                 goto fail;
691         } else {
692                 printf("tenth delete on close test succeeded.\n");
693         }
694
695   fail:
696
697         return correct;
698 }
699
700 /* Test 11 ... */
701 static BOOL deltest11(struct smbcli_state *cli1, struct smbcli_state *cli2)
702 {
703         int fnum1 = -1;
704         NTSTATUS status;
705
706         del_clean_area(cli1, cli2);
707
708         /* test 11 - does having read only attribute still allow delete on close. */
709
710         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
711                                       SEC_RIGHTS_FILE_ALL,
712                                       FILE_ATTRIBUTE_READONLY, 
713                                       NTCREATEX_SHARE_ACCESS_NONE, 
714                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
715         
716         if (fnum1 == -1) {
717                 printf("(%s) open of %s failed (%s)\n", 
718                        __location__, fname, smbcli_errstr(cli1->tree));
719                 return False;
720         }
721
722         status = smbcli_nt_delete_on_close(cli1->tree, fnum1, True);
723
724         if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
725                 printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n", 
726                        __location__, smbcli_errstr(cli1->tree));
727                 return False;
728         }
729
730         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
731                 printf("(%s) close failed (%s)\n", 
732                        __location__, smbcli_errstr(cli1->tree));
733                 return False;
734         }
735
736         printf("eleventh delete on close test succeeded.\n");
737         return True;
738 }
739
740 /* Test 12 ... */
741 static BOOL deltest12(struct smbcli_state *cli1, struct smbcli_state *cli2)
742 {
743         int fnum1 = -1;
744         NTSTATUS status;
745
746         del_clean_area(cli1, cli2);
747
748         /* test 12 - does having read only attribute still allow delete on
749          * close at time of open. */
750
751         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
752                                       SEC_RIGHTS_FILE_ALL,
753                                       FILE_ATTRIBUTE_READONLY,
754                                       NTCREATEX_SHARE_ACCESS_DELETE,
755                                       NTCREATEX_DISP_OVERWRITE_IF, 
756                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
757         
758         if (fnum1 != -1) {
759                 printf("(%s) open of %s succeeded. Should fail with "
760                        "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
761                 smbcli_close(cli1->tree, fnum1);
762                 return False;
763         } else {
764                 status = smbcli_nt_error(cli1->tree);
765                 if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
766                         printf("(%s) setting delete_on_close on open should "
767                                "fail with NT_STATUS_CANNOT_DELETE. Got %s "
768                                "instead)\n", 
769                                __location__, smbcli_errstr(cli1->tree));
770                         return False;
771                 }
772         }
773         
774         printf("twelvth delete on close test succeeded.\n");
775         return True;
776 }
777
778 /* Test 13 ... */
779 static BOOL deltest13(struct smbcli_state *cli1, struct smbcli_state *cli2)
780 {
781         int fnum1 = -1;
782         int fnum2 = -1;
783         BOOL correct = True;
784
785         del_clean_area(cli1, cli2);
786
787         /* Test 13: Does resetting the delete on close flag affect a second
788          * fd? */
789
790         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
791                                       SEC_FILE_READ_DATA|
792                                       SEC_FILE_WRITE_DATA|
793                                       SEC_STD_DELETE,
794                                       FILE_ATTRIBUTE_NORMAL, 
795                                       NTCREATEX_SHARE_ACCESS_READ|
796                                       NTCREATEX_SHARE_ACCESS_WRITE|
797                                       NTCREATEX_SHARE_ACCESS_DELETE,
798                                       NTCREATEX_DISP_OVERWRITE_IF,
799                                       0, 0);
800         
801         if (fnum1 == -1) {
802                 printf("(%s) open of %s failed (%s)\n", 
803                        __location__, fname, smbcli_errstr(cli1->tree));
804                 correct = False;
805                 goto fail;
806         }
807
808         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, 
809                                       SEC_FILE_READ_DATA|
810                                       SEC_FILE_WRITE_DATA|
811                                       SEC_STD_DELETE,
812                                       FILE_ATTRIBUTE_NORMAL, 
813                                       NTCREATEX_SHARE_ACCESS_READ|
814                                       NTCREATEX_SHARE_ACCESS_WRITE|
815                                       NTCREATEX_SHARE_ACCESS_DELETE,
816                                       NTCREATEX_DISP_OPEN, 0, 0);
817         
818         if (fnum2 == -1) {
819                 printf("(%s) open of %s failed (%s)\n", 
820                        __location__, fname, smbcli_errstr(cli2->tree));
821                 correct = False;
822                 goto fail;
823         }
824
825         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1,
826                                                        True))) {
827                 printf("(%s) setting delete_on_close on file failed !\n",
828                        __location__);
829                 correct = False;
830                 goto fail;
831         }
832
833         correct &= check_delete_on_close(cli1, fnum1, fname, True);
834         correct &= check_delete_on_close(cli2, fnum2, fname, True);
835
836         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli2->tree, fnum2,
837                                                        False))) {
838                 printf("(%s) setting delete_on_close on file failed !\n",
839                        __location__);
840                 correct = False;
841                 goto fail;
842         }
843
844         correct &= check_delete_on_close(cli1, fnum1, fname, False);
845         correct &= check_delete_on_close(cli2, fnum2, fname, False);
846         
847         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
848                 printf("(%s) close - 1 failed (%s)\n", 
849                        __location__, smbcli_errstr(cli1->tree));
850                 correct = False;
851                 goto fail;
852         }
853
854         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
855                 printf("(%s) close - 2 failed (%s)\n", 
856                        __location__, smbcli_errstr(cli2->tree));
857                 correct = False;
858                 goto fail;
859         }
860
861         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
862
863         if (fnum1 == -1) {
864                 printf("(%s) open of %s failed!\n", 
865                        __location__, fname);
866                 correct = False;
867                 goto fail;
868         }
869
870         printf("thirteenth delete on close test succeeded.\n");
871
872   fail:
873
874         return correct;
875 }
876
877 /* Test 14 ... */
878 static BOOL deltest14(struct smbcli_state *cli1, struct smbcli_state *cli2)
879 {
880         int dnum1 = -1;
881         BOOL correct = True;
882
883         del_clean_area(cli1, cli2);
884
885         /* Test 14 -- directory */
886
887         dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
888                                       SEC_FILE_READ_DATA|
889                                       SEC_FILE_WRITE_DATA|
890                                       SEC_STD_DELETE,
891                                       FILE_ATTRIBUTE_DIRECTORY, 
892                                       NTCREATEX_SHARE_ACCESS_READ|
893                                       NTCREATEX_SHARE_ACCESS_WRITE|
894                                       NTCREATEX_SHARE_ACCESS_DELETE,
895                                       NTCREATEX_DISP_CREATE, 0, 0);
896         if (dnum1 == -1) {
897                 printf("(%s) open of %s failed: %s!\n", 
898                        __location__, dirname, smbcli_errstr(cli1->tree));
899                 correct = False;
900                 goto fail;
901         }
902
903         check_delete_on_close(cli1, dnum1, dirname, False);
904         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, dnum1, True))) {
905                 printf("(%s) setting delete_on_close on file failed !\n",
906                        __location__);
907                 correct = False;
908                 goto fail;
909         }
910         check_delete_on_close(cli1, dnum1, dirname, True);
911         smbcli_close(cli1->tree, dnum1);
912
913         /* Now it should be gone... */
914
915         dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
916                                       SEC_FILE_READ_DATA|
917                                       SEC_FILE_WRITE_DATA|
918                                       SEC_STD_DELETE,
919                                       FILE_ATTRIBUTE_DIRECTORY, 
920                                       NTCREATEX_SHARE_ACCESS_READ|
921                                       NTCREATEX_SHARE_ACCESS_WRITE|
922                                       NTCREATEX_SHARE_ACCESS_DELETE,
923                                       NTCREATEX_DISP_OPEN, 0, 0);
924         if (dnum1 != -1) {
925                 printf("(%s) setting delete_on_close on file succeeded !\n",
926                        __location__);
927                 correct = False;
928                 goto fail;
929         }
930
931         printf("fourteenth delete on close test succeeded.\n");
932
933   fail:
934
935         return correct;
936 }
937
938 /* Test 15 ... */
939 static BOOL deltest15(struct smbcli_state *cli1, struct smbcli_state *cli2)
940 {
941         int fnum1 = -1;
942         int fnum2 = -1;
943         BOOL correct = True;
944         NTSTATUS status;
945
946         del_clean_area(cli1, cli2);
947
948         /* Test 15: delete on close under rename */
949
950         smbcli_setatr(cli1->tree, fname, 0, 0);
951         smbcli_unlink(cli1->tree, fname);
952         smbcli_unlink(cli1->tree, fname_new);
953         
954         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
955                                       SEC_FILE_READ_DATA,
956                                       FILE_ATTRIBUTE_NORMAL, 
957                                       NTCREATEX_SHARE_ACCESS_READ|
958                                       NTCREATEX_SHARE_ACCESS_WRITE|
959                                       NTCREATEX_SHARE_ACCESS_DELETE,
960                                       NTCREATEX_DISP_OVERWRITE_IF,
961                                       0, 0);
962
963         if (fnum1 == -1) {
964                 printf("(%s) open - 1 of %s failed (%s)\n", 
965                        __location__, fname, smbcli_errstr(cli1->tree));
966                 correct = False;
967                 goto fail;
968         }
969
970         status = smbcli_rename(cli2->tree, fname, fname_new);
971
972         if (!NT_STATUS_IS_OK(status)) {
973                 printf("(%s) renaming failed: %s !\n",
974                        __location__, nt_errstr(status));
975                 correct = False;
976                 goto fail;
977         }
978
979         fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0, 
980                                       SEC_GENERIC_ALL,
981                                       FILE_ATTRIBUTE_NORMAL, 
982                                       NTCREATEX_SHARE_ACCESS_READ|
983                                       NTCREATEX_SHARE_ACCESS_WRITE|
984                                       NTCREATEX_SHARE_ACCESS_DELETE,
985                                       NTCREATEX_DISP_OVERWRITE_IF,
986                                       0, 0);
987
988         if (fnum2 == -1) {
989                 printf("(%s) open - 1 of %s failed (%s)\n", 
990                        __location__, fname_new, smbcli_errstr(cli1->tree));
991                 correct = False;
992                 goto fail;
993         }
994
995         status = smbcli_nt_delete_on_close(cli2->tree, fnum2, True);
996
997         if (!NT_STATUS_IS_OK(status)) {
998                 printf("(%s) setting delete_on_close on file failed !\n",
999                        __location__);
1000                 correct = False;
1001                 goto fail;
1002         }
1003
1004         smbcli_close(cli2->tree, fnum2);
1005
1006         /* The file should be around under the new name, there's a second
1007          * handle open */
1008
1009         if (!check_delete_on_close(cli1, fnum1, fname_new, True)) {
1010                 printf("(%s) checking delete on close on file %s failed!\n",
1011                        __location__, fname_new);
1012                 correct = False;
1013                 goto fail;
1014         }
1015
1016         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, 
1017                                       SEC_GENERIC_ALL,
1018                                       FILE_ATTRIBUTE_NORMAL, 
1019                                       NTCREATEX_SHARE_ACCESS_READ|
1020                                       NTCREATEX_SHARE_ACCESS_WRITE|
1021                                       NTCREATEX_SHARE_ACCESS_DELETE,
1022                                       NTCREATEX_DISP_OVERWRITE_IF,
1023                                       0, 0);
1024
1025         if (fnum2 == -1) {
1026                 printf("(%s) open - 1 of %s failed (%s)\n", 
1027                        __location__, fname, smbcli_errstr(cli1->tree));
1028                 correct = False;
1029                 goto fail;
1030         }
1031
1032         smbcli_close(cli2->tree, fnum2);
1033         smbcli_close(cli1->tree, fnum1);
1034
1035         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1036                                       SEC_FILE_READ_EA,
1037                                       FILE_ATTRIBUTE_NORMAL, 
1038                                       NTCREATEX_SHARE_ACCESS_READ|
1039                                       NTCREATEX_SHARE_ACCESS_WRITE|
1040                                       NTCREATEX_SHARE_ACCESS_DELETE,
1041                                       NTCREATEX_DISP_OPEN,
1042                                       0, 0);
1043
1044         if (fnum1 == -1) {
1045                 printf("(%s) open - 1 of %s failed (%s)\n", 
1046                        __location__, fname, smbcli_errstr(cli1->tree));
1047                 correct = False;
1048                 goto fail;
1049         }
1050
1051         smbcli_close(cli1->tree, fnum1);
1052
1053         fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0, 
1054                                       SEC_FILE_READ_EA,
1055                                       FILE_ATTRIBUTE_NORMAL, 
1056                                       NTCREATEX_SHARE_ACCESS_READ|
1057                                       NTCREATEX_SHARE_ACCESS_WRITE|
1058                                       NTCREATEX_SHARE_ACCESS_DELETE,
1059                                       NTCREATEX_DISP_OPEN,
1060                                       0, 0);
1061
1062         if (fnum1 != -1) {
1063                 printf("(%s) smbcli_open succeeded, should have "
1064                        "failed\n", __location__);
1065                 smbcli_close(cli1->tree, fnum1);
1066                 correct = False;
1067                 goto fail;
1068         }
1069
1070         printf("fifteenth delete on close test succeeded.\n");
1071
1072   fail:
1073
1074         return correct;
1075 }
1076
1077 /* Test 16 ... */
1078 static BOOL deltest16(struct smbcli_state *cli1, struct smbcli_state *cli2)
1079 {
1080         int fnum1 = -1;
1081         int fnum2 = -1;
1082         BOOL correct = True;
1083
1084         del_clean_area(cli1, cli2);
1085
1086         /* Test 16. */
1087
1088         /* Ensure the file doesn't already exist. */
1089         smbcli_close(cli1->tree, fnum1);
1090         smbcli_close(cli1->tree, fnum2);
1091         smbcli_setatr(cli1->tree, fname, 0, 0);
1092         smbcli_unlink(cli1->tree, fname);
1093
1094         /* Firstly create with all access, but delete on close. */
1095         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1096                                       SEC_RIGHTS_FILE_ALL,
1097                                       FILE_ATTRIBUTE_NORMAL,
1098                                       NTCREATEX_SHARE_ACCESS_READ|
1099                                       NTCREATEX_SHARE_ACCESS_WRITE|
1100                                       NTCREATEX_SHARE_ACCESS_DELETE,
1101                                       NTCREATEX_DISP_CREATE,
1102                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1103         
1104         if (fnum1 == -1) {
1105                 printf("(%s) open - 1 of %s failed (%s)\n", 
1106                        __location__, fname, smbcli_errstr(cli1->tree));
1107                 correct = False;
1108                 goto fail;
1109         }
1110
1111         /* The delete on close bit is *not* reported as being set. */
1112         check_delete_on_close(cli1, fnum1, fname, False);
1113
1114         /* Now try opening again for read-only. */
1115         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1116                                       SEC_RIGHTS_FILE_READ,
1117                                       FILE_ATTRIBUTE_NORMAL,
1118                                       NTCREATEX_SHARE_ACCESS_READ|
1119                                       NTCREATEX_SHARE_ACCESS_WRITE|
1120                                       NTCREATEX_SHARE_ACCESS_DELETE,
1121                                       NTCREATEX_DISP_OPEN,
1122                                       0, 0);
1123         
1124
1125         /* Should work. */
1126         if (fnum2 == -1) {
1127                 printf("(%s) open - 1 of %s failed (%s)\n", 
1128                        __location__, fname, smbcli_errstr(cli1->tree));
1129                 correct = False;
1130                 goto fail;
1131         }
1132
1133         /* Now close both.... */
1134         smbcli_close(cli1->tree, fnum1);
1135         smbcli_close(cli1->tree, fnum2);
1136
1137         /* And the file should be deleted ! */
1138         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1139         if (fnum1 != -1) {
1140                 printf("(%s) open of %s succeeded (should fail)\n", 
1141                        __location__, fname);
1142                 correct = False;
1143                 goto fail;
1144         }
1145         
1146         printf("sixteenth delete on close test succeeded.\n");
1147
1148   fail:
1149
1150         return correct;
1151 }
1152
1153 /* Test 17 ... */
1154 static BOOL deltest17(struct smbcli_state *cli1, struct smbcli_state *cli2)
1155 {
1156         int fnum1 = -1;
1157         int fnum2 = -1;
1158         BOOL correct = True;
1159
1160         del_clean_area(cli1, cli2);
1161
1162         /* Test 17. */
1163
1164         /* Ensure the file doesn't already exist. */
1165         smbcli_close(cli1->tree, fnum1);
1166         smbcli_close(cli1->tree, fnum2);
1167         smbcli_setatr(cli1->tree, fname, 0, 0);
1168         smbcli_unlink(cli1->tree, fname);
1169
1170         /* Firstly open and create with all access */
1171         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1172                                       SEC_RIGHTS_FILE_ALL,
1173                                       FILE_ATTRIBUTE_NORMAL,
1174                                       NTCREATEX_SHARE_ACCESS_READ|
1175                                       NTCREATEX_SHARE_ACCESS_WRITE|
1176                                       NTCREATEX_SHARE_ACCESS_DELETE,
1177                                       NTCREATEX_DISP_CREATE, 
1178                                       0, 0);
1179         if (fnum1 == -1) {
1180                 printf("(%s) open - 1 of %s failed (%s)\n", 
1181                        __location__, fname, smbcli_errstr(cli1->tree));
1182                 correct = False;
1183                 goto fail;
1184         }
1185
1186         /* And close - just to create the file. */
1187         smbcli_close(cli1->tree, fnum1);
1188         
1189         /* Next open with all access, but add delete on close. */
1190         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1191                                       SEC_RIGHTS_FILE_ALL,
1192                                       FILE_ATTRIBUTE_NORMAL,
1193                                       NTCREATEX_SHARE_ACCESS_READ|
1194                                       NTCREATEX_SHARE_ACCESS_WRITE|
1195                                       NTCREATEX_SHARE_ACCESS_DELETE,
1196                                       NTCREATEX_DISP_OPEN,
1197                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1198         
1199         if (fnum1 == -1) {
1200                 printf("(%s) open - 1 of %s failed (%s)\n", 
1201                        __location__, fname, smbcli_errstr(cli1->tree));
1202                 correct = False;
1203                 goto fail;
1204         }
1205
1206         /* The delete on close bit is *not* reported as being set. */
1207         check_delete_on_close(cli1, fnum1, fname, False);
1208
1209         /* Now try opening again for read-only. */
1210         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1211                                       SEC_RIGHTS_FILE_READ|
1212                                       SEC_STD_DELETE,
1213                                       FILE_ATTRIBUTE_NORMAL,
1214                                       NTCREATEX_SHARE_ACCESS_READ|
1215                                       NTCREATEX_SHARE_ACCESS_WRITE|
1216                                       NTCREATEX_SHARE_ACCESS_DELETE,
1217                                       NTCREATEX_DISP_OPEN,
1218                                       0, 0);
1219         
1220         /* Should work. */
1221         if (fnum2 == -1) {
1222                 printf("(%s) open - 1 of %s failed (%s)\n", 
1223                        __location__, fname, smbcli_errstr(cli1->tree));
1224                 correct = False;
1225                 goto fail;
1226         }
1227
1228         /* Now close both.... */
1229         smbcli_close(cli1->tree, fnum1);
1230         smbcli_close(cli1->tree, fnum2);
1231
1232         /* See if the file is deleted - shouldn't be.... */
1233         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1234         if (fnum1 == -1) {
1235                 printf("(%s) open of %s failed (should succeed) - %s\n", 
1236                        __location__, fname, smbcli_errstr(cli1->tree));
1237                 correct = False;
1238                 goto fail;
1239         }
1240         
1241         printf("seventeenth delete on close test succeeded.\n");
1242
1243   fail:
1244
1245         return correct;
1246 }
1247
1248 /* Test 18 ... */
1249 static BOOL deltest18(struct smbcli_state *cli1, struct smbcli_state *cli2)
1250 {
1251         int fnum1 = -1;
1252         int fnum2 = -1;
1253         BOOL correct = True;
1254
1255         del_clean_area(cli1, cli2);
1256
1257         /* Test 18. With directories. */
1258
1259         /* Ensure the file doesn't already exist. */
1260         smbcli_close(cli1->tree, fnum1);
1261         smbcli_close(cli1->tree, fnum2);
1262
1263         smbcli_deltree(cli1->tree, dirname);
1264
1265         /* Firstly create with all access, but delete on close. */
1266         fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
1267                                       SEC_FILE_READ_DATA|
1268                                       SEC_FILE_WRITE_DATA|
1269                                       SEC_STD_DELETE,
1270                                       FILE_ATTRIBUTE_DIRECTORY,
1271                                       NTCREATEX_SHARE_ACCESS_READ|
1272                                       NTCREATEX_SHARE_ACCESS_WRITE|
1273                                       NTCREATEX_SHARE_ACCESS_DELETE,
1274                                       NTCREATEX_DISP_CREATE,
1275                                       NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1276         
1277         if (fnum1 == -1) {
1278                 printf("(%s) open - 1 of %s failed (%s)\n", 
1279                        __location__, dirname, smbcli_errstr(cli1->tree));
1280                 correct = False;
1281                 goto fail;
1282         }
1283
1284         /* The delete on close bit is *not* reported as being set. */
1285         check_delete_on_close(cli1, fnum1, dirname, False);
1286
1287         /* Now try opening again for read-only. */
1288         fnum2 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
1289                                       SEC_RIGHTS_FILE_READ,
1290                                       FILE_ATTRIBUTE_DIRECTORY,
1291                                       NTCREATEX_SHARE_ACCESS_READ|
1292                                       NTCREATEX_SHARE_ACCESS_WRITE|
1293                                       NTCREATEX_SHARE_ACCESS_DELETE,
1294                                       NTCREATEX_DISP_OPEN,
1295                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
1296         
1297
1298         /* Should work. */
1299         if (fnum2 == -1) {
1300                 printf("(%s) open - 1 of %s failed (%s)\n", 
1301                        __location__, dirname, smbcli_errstr(cli1->tree));
1302                 correct = False;
1303                 goto fail;
1304         }
1305
1306         /* Now close both.... */
1307         smbcli_close(cli1->tree, fnum1);
1308         smbcli_close(cli1->tree, fnum2);
1309
1310         /* And the directory should be deleted ! */
1311         fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
1312                                       SEC_RIGHTS_FILE_READ,
1313                                       FILE_ATTRIBUTE_DIRECTORY,
1314                                       NTCREATEX_SHARE_ACCESS_READ|
1315                                       NTCREATEX_SHARE_ACCESS_WRITE|
1316                                       NTCREATEX_SHARE_ACCESS_DELETE,
1317                                       NTCREATEX_DISP_OPEN,
1318                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
1319         if (fnum1 != -1) {
1320                 printf("(%s) open of %s succeeded (should fail)\n", 
1321                        __location__, dirname);
1322                 correct = False;
1323                 goto fail;
1324         }
1325         
1326         printf("eighteenth delete on close test succeeded.\n");
1327
1328   fail:
1329
1330         return correct;
1331 }
1332
1333 /* Test 19 ... */
1334 static BOOL deltest19(struct smbcli_state *cli1, struct smbcli_state *cli2)
1335 {
1336         int fnum1 = -1;
1337         int fnum2 = -1;
1338         BOOL correct = True;
1339
1340         del_clean_area(cli1, cli2);
1341
1342         /* Test 19. */
1343
1344         smbcli_deltree(cli1->tree, dirname);
1345
1346         /* Firstly open and create with all access */
1347         fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
1348                                       SEC_FILE_READ_DATA|
1349                                       SEC_FILE_WRITE_DATA|
1350                                       SEC_STD_DELETE,
1351                                       FILE_ATTRIBUTE_DIRECTORY,
1352                                       NTCREATEX_SHARE_ACCESS_READ|
1353                                       NTCREATEX_SHARE_ACCESS_WRITE|
1354                                       NTCREATEX_SHARE_ACCESS_DELETE,
1355                                       NTCREATEX_DISP_CREATE,
1356                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
1357         
1358         if (fnum1 == -1) {
1359                 printf("(%s) open - 1 of %s failed (%s)\n", 
1360                        __location__, dirname, smbcli_errstr(cli1->tree));
1361                 correct = False;
1362                 goto fail;
1363         }
1364
1365         /* And close - just to create the directory. */
1366         smbcli_close(cli1->tree, fnum1);
1367         
1368         /* Next open with all access, but add delete on close. */
1369         fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 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_OPEN,
1378                                       NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
1379         
1380         if (fnum1 == -1) {
1381                 printf("(%s) open - 1 of %s failed (%s)\n", 
1382                        __location__, fname, smbcli_errstr(cli1->tree));
1383                 correct = False;
1384                 goto fail;
1385         }
1386
1387         /* The delete on close bit is *not* reported as being set. */
1388         check_delete_on_close(cli1, fnum1, dirname, False);
1389
1390         /* Now try opening again for read-only. */
1391         fnum2 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
1392                                       SEC_RIGHTS_FILE_READ,
1393                                       FILE_ATTRIBUTE_DIRECTORY,
1394                                       NTCREATEX_SHARE_ACCESS_READ|
1395                                       NTCREATEX_SHARE_ACCESS_WRITE|
1396                                       NTCREATEX_SHARE_ACCESS_DELETE,
1397                                       NTCREATEX_DISP_OPEN,
1398                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
1399         
1400         /* Should work. */
1401         if (fnum2 == -1) {
1402                 printf("(%s) open - 1 of %s failed (%s)\n", 
1403                        __location__, dirname, smbcli_errstr(cli1->tree));
1404                 correct = False;
1405                 goto fail;
1406         }
1407
1408         /* Now close both.... */
1409         smbcli_close(cli1->tree, fnum1);
1410         smbcli_close(cli1->tree, fnum2);
1411
1412         /* See if the file is deleted - for a directory this seems to be true ! */
1413         fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 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);
1421
1422         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1423
1424         if (fnum1 != -1) {
1425                 printf("(%s) open of %s succeeded (should fail)\n", 
1426                        __location__, dirname);
1427                 correct = False;
1428                 goto fail;
1429         }
1430
1431         printf("nineteenth delete on close test succeeded.\n");
1432
1433   fail:
1434
1435         return correct;
1436 }
1437
1438 /* Test 20 ... */
1439 static BOOL deltest20(struct smbcli_state *cli1, struct smbcli_state *cli2)
1440 {
1441         int fnum1 = -1;
1442         int dnum1 = -1;
1443         BOOL correct = True;
1444         NTSTATUS status;
1445
1446         del_clean_area(cli1, cli2);
1447
1448         /* Test 20 -- non-empty directory hardest to get right... */
1449
1450         smbcli_deltree(cli1->tree, dirname);
1451
1452         dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
1453                                       SEC_FILE_READ_DATA|
1454                                       SEC_FILE_WRITE_DATA|
1455                                       SEC_STD_DELETE,
1456                                       FILE_ATTRIBUTE_DIRECTORY, 
1457                                       NTCREATEX_SHARE_ACCESS_READ|
1458                                       NTCREATEX_SHARE_ACCESS_WRITE|
1459                                       NTCREATEX_SHARE_ACCESS_DELETE,
1460                                       NTCREATEX_DISP_CREATE, 
1461                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
1462         if (dnum1 == -1) {
1463                 printf("(%s) open of %s failed: %s!\n", 
1464                        __location__, dirname, smbcli_errstr(cli1->tree));
1465                 correct = False;
1466                 goto fail;
1467         }
1468
1469         check_delete_on_close(cli1, dnum1, dirname, False);
1470         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1471
1472         {
1473                 char *fullname;
1474                 asprintf(&fullname, "\\%s%s", dirname, fname);
1475                 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1476                                     DENY_NONE);
1477                 if (fnum1 != -1) {
1478                         printf("(%s) smbcli_open succeeded, should have "
1479                                "failed: %s\n",
1480                                __location__, smbcli_errstr(cli1->tree));
1481                         correct = False;
1482                         goto fail;
1483                 }
1484
1485                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree),
1486                                      NT_STATUS_DELETE_PENDING)) {
1487                         printf("(%s) smbcli_open returned %s, expected "
1488                                "NT_STATUS_DELETE_PENDING\n",
1489                                __location__, smbcli_errstr(cli1->tree));
1490                         correct = False;
1491                         goto fail;
1492                 }
1493         }
1494
1495         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, False);
1496         if (!NT_STATUS_IS_OK(status)) {
1497                 printf("(%s) setting delete_on_close on file failed !\n",
1498                        __location__);
1499                 correct = False;
1500                 goto fail;
1501         }
1502                 
1503         {
1504                 char *fullname;
1505                 asprintf(&fullname, "\\%s%s", dirname, fname);
1506                 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
1507                                     DENY_NONE);
1508                 if (fnum1 == -1) {
1509                         printf("(%s) smbcli_open failed: %s\n",
1510                                __location__, smbcli_errstr(cli1->tree));
1511                         correct = False;
1512                         goto fail;
1513                 }
1514                 smbcli_close(cli1->tree, fnum1);
1515         }
1516
1517         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True);
1518
1519         if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1520                 printf("(%s) setting delete_on_close returned %s, expected "
1521                        "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__,
1522                        smbcli_errstr(cli1->tree));
1523                 correct = False;
1524                 goto fail;
1525         }
1526
1527         smbcli_close(cli1->tree, dnum1);
1528
1529         printf("twentieth delete on close test succeeded.\n");
1530
1531   fail:
1532
1533         return correct;
1534 }
1535
1536 /* Test 21 ... */
1537 static BOOL deltest21(struct smbcli_state **ppcli1, struct smbcli_state **ppcli2)
1538 {
1539         int fnum1 = -1;
1540         struct smbcli_state *cli1 = *ppcli1;
1541         struct smbcli_state *cli2 = *ppcli2;
1542         BOOL correct = True;
1543
1544         del_clean_area(cli1, cli2);
1545
1546         /* Test 21 -- Test removal of file after socket close. */
1547
1548         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1549                                       SEC_RIGHTS_FILE_ALL,
1550                                       FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, 
1551                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1552         
1553         if (fnum1 == -1) {
1554                 printf("(%s) open of %s failed (%s)\n", 
1555                        __location__, fname, smbcli_errstr(cli1->tree));
1556                 return False;
1557         }
1558         
1559         if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
1560                 printf("(%s) setting delete_on_close failed (%s)\n", 
1561                        __location__, smbcli_errstr(cli1->tree));
1562                 return False;
1563         }
1564         
1565         /* Ensure delete on close is set. */
1566         check_delete_on_close(cli1, fnum1, fname, True);
1567
1568         /* Now yank the rug from under cli1. */
1569         smbcli_transport_dead(cli1->transport);
1570
1571         fnum1 = -1;
1572
1573         if (!torture_open_connection(ppcli1)) {
1574                 return False;
1575         }
1576
1577         cli1 = *ppcli1;
1578
1579         /* File should not be there. */
1580         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
1581                                       SEC_RIGHTS_FILE_READ,
1582                                       FILE_ATTRIBUTE_NORMAL,
1583                                       NTCREATEX_SHARE_ACCESS_READ|
1584                                       NTCREATEX_SHARE_ACCESS_WRITE|
1585                                       NTCREATEX_SHARE_ACCESS_DELETE,
1586                                       NTCREATEX_DISP_OPEN,
1587                                       0, 0);
1588         
1589         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
1590
1591         printf("twenty-first delete on close test succeeded.\n");
1592
1593   fail:
1594
1595         return correct;
1596 }
1597         
1598 /*
1599   Test delete on close semantics.
1600  */
1601 BOOL torture_test_delete(void)
1602 {
1603         struct smbcli_state *cli1 = NULL;
1604         struct smbcli_state *cli2 = NULL;
1605         BOOL correct = True;
1606         
1607         printf("starting delete test\n");
1608         
1609         if (!torture_open_connection(&cli1)) {
1610                 return False;
1611         }
1612
1613         if (!torture_open_connection(&cli2)) {
1614                 printf("(%s) failed to open second connection.\n",
1615                        __location__);
1616                 correct = False;
1617                 goto fail;
1618         }
1619
1620         correct &= deltest1(cli1, cli2);
1621         correct &= deltest2(cli1, cli2);
1622         correct &= deltest3(cli1, cli2);
1623         correct &= deltest4(cli1, cli2);
1624         correct &= deltest5(cli1, cli2);
1625         correct &= deltest6(cli1, cli2);
1626         correct &= deltest7(cli1, cli2);
1627         correct &= deltest8(cli1, cli2);
1628         correct &= deltest9(cli1, cli2);
1629         correct &= deltest10(cli1, cli2);
1630         correct &= deltest11(cli1, cli2);
1631         correct &= deltest12(cli1, cli2);
1632         correct &= deltest13(cli1, cli2);
1633         correct &= deltest14(cli1, cli2);
1634         correct &= deltest15(cli1, cli2);
1635         correct &= deltest16(cli1, cli2);
1636         correct &= deltest17(cli1, cli2);
1637         correct &= deltest18(cli1, cli2);
1638         correct &= deltest19(cli1, cli2);
1639         correct &= deltest20(cli1, cli2);
1640         correct &= deltest21(&cli1, &cli2);
1641
1642         if (!correct) {
1643                 printf("Failed delete test\n");
1644         } else {
1645                 printf("delete test ok !\n");
1646         }
1647
1648   fail:
1649         del_clean_area(cli1, cli2);
1650
1651         if (!torture_close_connection(cli1)) {
1652                 correct = False;
1653         }
1654         if (!torture_close_connection(cli2)) {
1655                 correct = False;
1656         }
1657         return correct;
1658 }