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