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