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