2 Unix SMB/CIFS implementation.
4 delete on close testing
6 Copyright (C) Andrew Tridgell 2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/libcli.h"
24 #include "torture/util.h"
25 #include "system/filesys.h"
26 #include "libcli/raw/raw_proto.h"
28 #include "torture/raw/proto.h"
29 #include "torture/basic/proto.h"
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
,
36 union smb_search_data data
;
39 time_t c_time
, a_time
, m_time
;
43 status
= torture_single_search(cli
, tctx
,
46 RAW_SEARCH_DATA_FULL_DIRECTORY_INFO
,
47 FILE_ATTRIBUTE_DIRECTORY
,
49 torture_assert_ntstatus_ok(tctx
, status
,
50 talloc_asprintf(tctx
, "single_search failed (%s)", where
));
53 union smb_fileinfo io
;
54 int nlink
= expect_it
? 0 : 1;
56 io
.all_info
.level
= RAW_FILEINFO_ALL_INFO
;
57 io
.all_info
.in
.file
.fnum
= fnum
;
59 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &io
);
60 torture_assert_ntstatus_ok(tctx
, status
, talloc_asprintf(tctx
,
61 "qfileinfo failed (%s)", where
));
63 torture_assert(tctx
, expect_it
== io
.all_info
.out
.delete_pending
,
65 "%s - Expected del_on_close flag %d, qfileinfo/all_info gave %d",
66 where
, expect_it
, io
.all_info
.out
.delete_pending
));
68 torture_assert(tctx
, nlink
== io
.all_info
.out
.nlink
,
70 "%s - Expected nlink %d, qfileinfo/all_info gave %d",
71 where
, nlink
, io
.all_info
.out
.nlink
));
73 io
.standard_info
.level
= RAW_FILEINFO_STANDARD_INFO
;
74 io
.standard_info
.in
.file
.fnum
= fnum
;
76 status
= smb_raw_fileinfo(cli
->tree
, tctx
, &io
);
77 torture_assert_ntstatus_ok(tctx
, status
, talloc_asprintf(tctx
, "qpathinfo failed (%s)", where
));
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
));
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
));
88 status
= smbcli_qpathinfo(cli
->tree
, fname
,
89 &c_time
, &a_time
, &m_time
,
93 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_DELETE_PENDING
,
94 "qpathinfo did not give correct error code");
96 torture_assert_ntstatus_ok(tctx
, status
,
97 talloc_asprintf(tctx
, "qpathinfo failed (%s)", where
));
103 #define CHECK_STATUS(_cli, _expected) \
104 torture_assert_ntstatus_equal(tctx, _cli->tree->session->transport->error.e.nt_status, _expected, \
107 static const char *fname
= "\\delete.file";
108 static const char *fname_new
= "\\delete.new";
109 static const char *dname
= "\\delete.dir";
111 static void del_clean_area(struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
113 smb_raw_exit(cli1
->session
);
114 smb_raw_exit(cli2
->session
);
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
);
123 /* Test 1 - this should delete the file on close. */
125 static bool deltest1(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
129 del_clean_area(cli1
, cli2
);
131 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
133 FILE_ATTRIBUTE_NORMAL
,
134 NTCREATEX_SHARE_ACCESS_DELETE
, NTCREATEX_DISP_OVERWRITE_IF
,
135 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
137 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
138 fname
, smbcli_errstr(cli1
->tree
)));
140 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
141 talloc_asprintf(tctx
, "close failed (%s)", smbcli_errstr(cli1
->tree
)));
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)",
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
)
155 del_clean_area(cli1
, cli2
);
157 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
159 FILE_ATTRIBUTE_NORMAL
, NTCREATEX_SHARE_ACCESS_NONE
,
160 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
162 torture_assert(tctx
, fnum1
!= -1,
163 talloc_asprintf(tctx
, "open of %s failed (%s)",
164 fname
, smbcli_errstr(cli1
->tree
)));
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
)));
170 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
171 talloc_asprintf(tctx
, "close failed (%s)",
172 smbcli_errstr(cli1
->tree
)));
174 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
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
));
183 smbcli_unlink(cli1
->tree
, fname
);
189 static bool deltest3(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
194 del_clean_area(cli1
, cli2
);
196 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
198 FILE_ATTRIBUTE_NORMAL
,
199 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
,
200 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
202 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
203 fname
, smbcli_errstr(cli1
->tree
)));
205 /* This should fail with a sharing violation - open for delete is only compatible
206 with SHARE_DELETE. */
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);
214 torture_assert(tctx
, fnum2
== -1,
215 talloc_asprintf(tctx
, "open - 2 of %s succeeded - should have failed.",
218 /* This should succeed. */
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);
226 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
227 fname
, smbcli_errstr(cli1
->tree
)));
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
)));
234 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
235 talloc_asprintf(tctx
, "close 1 failed (%s)",
236 smbcli_errstr(cli1
->tree
)));
238 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum2
),
239 talloc_asprintf(tctx
, "close 2 failed (%s)",
240 smbcli_errstr(cli1
->tree
)));
242 /* This should fail - file should no longer be there. */
244 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
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
));
252 smbcli_unlink(cli1
->tree
, fname
);
259 static bool deltest4(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
265 del_clean_area(cli1
, cli2
);
267 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
269 SEC_FILE_WRITE_DATA
|
271 FILE_ATTRIBUTE_NORMAL
,
272 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
,
273 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
275 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
276 fname
, smbcli_errstr(cli1
->tree
)));
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
)));
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
)));
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
)));
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.",
309 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
311 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
312 talloc_asprintf(tctx
, "close - 2 failed (%s)",
313 smbcli_errstr(cli1
->tree
)));
319 static bool deltest5(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
323 del_clean_area(cli1
, cli2
);
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
)));
329 /* This should fail - only allowed on NT opens with DELETE access. */
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 !");
334 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
335 talloc_asprintf(tctx
, "close - 2 failed (%s)", smbcli_errstr(cli1
->tree
)));
341 static bool deltest6(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
345 del_clean_area(cli1
, cli2
);
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);
355 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
356 fname
, smbcli_errstr(cli1
->tree
)));
358 /* This should fail - only allowed on NT opens with DELETE access. */
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 !");
364 torture_assert_ntstatus_ok(tctx
,
365 smbcli_close(cli1
->tree
, fnum1
),
366 talloc_asprintf(tctx
,
367 "close - 2 failed (%s)",
368 smbcli_errstr(cli1
->tree
)));
374 static bool deltest7(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
379 del_clean_area(cli1
, cli2
);
381 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
383 SEC_FILE_WRITE_DATA
|
385 FILE_ATTRIBUTE_NORMAL
, 0,
386 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
388 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
389 fname
, smbcli_errstr(cli1
->tree
)));
391 torture_assert_ntstatus_ok(tctx
, smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true),
392 "setting delete_on_close on file failed !");
394 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
396 torture_assert_ntstatus_ok(tctx
,
397 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, false),
398 "unsetting delete_on_close on file failed !");
400 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
402 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
403 talloc_asprintf(tctx
, "close - 2 failed (%s)", smbcli_errstr(cli1
->tree
)));
405 /* This next open should succeed - we reset the flag. */
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
)));
411 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
412 talloc_asprintf(tctx
, "close - 2 failed (%s)",
413 smbcli_errstr(cli1
->tree
)));
419 static bool deltest8(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
425 del_clean_area(cli1
, cli2
);
427 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
431 FILE_ATTRIBUTE_NORMAL
,
432 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
433 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
435 torture_assert(tctx
, fnum1
!= -1,
436 talloc_asprintf(tctx
, "open of %s failed (%s)",
437 fname
, smbcli_errstr(cli1
->tree
)));
439 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
443 FILE_ATTRIBUTE_NORMAL
,
444 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
|NTCREATEX_SHARE_ACCESS_DELETE
,
445 NTCREATEX_DISP_OPEN
, 0, 0);
447 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
448 fname
, smbcli_errstr(cli1
->tree
)));
450 torture_assert_ntstatus_ok(tctx
,
451 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true),
452 "setting delete_on_close on file failed !");
454 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
455 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
457 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
458 talloc_asprintf(tctx
, "close - 1 failed (%s)",
459 smbcli_errstr(cli1
->tree
)));
461 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, true, __location__
);
462 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
464 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli2
->tree
, fnum2
),
465 talloc_asprintf(tctx
, "close - 2 failed (%s)", smbcli_errstr(cli2
->tree
)));
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
));
476 static bool deltest9(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
480 del_clean_area(cli1
, cli2
);
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);
490 torture_assert(tctx
, fnum1
== -1,
491 talloc_asprintf(tctx
, "open of %s succeeded should have failed!",
498 static bool deltest10(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
502 del_clean_area(cli1
, cli2
);
504 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
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
)));
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
)));
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 !",
530 static bool deltest11(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
535 del_clean_area(cli1
, cli2
);
537 /* test 11 - does having read only attribute still allow delete on close. */
539 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
541 FILE_ATTRIBUTE_READONLY
,
542 NTCREATEX_SHARE_ACCESS_NONE
,
543 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
545 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
546 fname
, smbcli_errstr(cli1
->tree
)));
548 status
= smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true);
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
)));
553 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
554 talloc_asprintf(tctx
, "close failed (%s)",
555 smbcli_errstr(cli1
->tree
)));
561 static bool deltest12(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
566 del_clean_area(cli1
, cli2
);
568 /* test 12 - does having read only attribute still allow delete on
569 * close at time of open. */
571 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
573 FILE_ATTRIBUTE_READONLY
,
574 NTCREATEX_SHARE_ACCESS_DELETE
,
575 NTCREATEX_DISP_OVERWRITE_IF
,
576 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
578 torture_assert(tctx
, fnum1
== -1,
579 talloc_asprintf(tctx
, "open of %s succeeded. Should fail with "
580 "NT_STATUS_CANNOT_DELETE.\n", fname
));
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 "
587 smbcli_errstr(cli1
->tree
)));
593 static bool deltest13(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
599 del_clean_area(cli1
, cli2
);
601 /* Test 13: Does resetting the delete on close flag affect a second
604 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
608 FILE_ATTRIBUTE_NORMAL
,
609 NTCREATEX_SHARE_ACCESS_READ
|
610 NTCREATEX_SHARE_ACCESS_WRITE
|
611 NTCREATEX_SHARE_ACCESS_DELETE
,
612 NTCREATEX_DISP_OVERWRITE_IF
,
615 torture_assert(tctx
, fnum1
!= -1,
616 talloc_asprintf(tctx
, "open of %s failed (%s)",
617 fname
, smbcli_errstr(cli1
->tree
)));
619 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
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);
629 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
,
630 "open of %s failed (%s)",
631 fname
, smbcli_errstr(cli2
->tree
)));
633 torture_assert_ntstatus_ok(tctx
,
634 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
,
636 "setting delete_on_close on file failed !");
638 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
639 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
641 torture_assert_ntstatus_ok(tctx
, smbcli_nt_delete_on_close(cli2
->tree
, fnum2
,
643 "setting delete_on_close on file failed !");
645 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
646 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
648 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
649 talloc_asprintf(tctx
, "close - 1 failed (%s)",
650 smbcli_errstr(cli1
->tree
)));
652 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli2
->tree
, fnum2
),
653 talloc_asprintf(tctx
, "close - 2 failed (%s)",
654 smbcli_errstr(cli2
->tree
)));
656 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
658 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed!",
661 smbcli_close(cli1
->tree
, fnum1
);
667 static bool deltest14(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
672 del_clean_area(cli1
, cli2
);
674 /* Test 14 -- directory */
676 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
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
)));
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
);
694 /* Now it should be gone... */
696 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
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 !");
711 static bool deltest15(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
718 del_clean_area(cli1
, cli2
);
720 /* Test 15: delete on close under rename */
722 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
723 smbcli_unlink(cli1
->tree
, fname
);
724 smbcli_unlink(cli1
->tree
, fname_new
);
726 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
728 FILE_ATTRIBUTE_NORMAL
,
729 NTCREATEX_SHARE_ACCESS_READ
|
730 NTCREATEX_SHARE_ACCESS_WRITE
|
731 NTCREATEX_SHARE_ACCESS_DELETE
,
732 NTCREATEX_DISP_OVERWRITE_IF
,
735 torture_assert(tctx
, fnum1
!= -1,
736 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
738 status
= smbcli_rename(cli2
->tree
, fname
, fname_new
);
740 torture_assert_ntstatus_ok(tctx
, status
, "renaming failed!");
742 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname_new
, 0,
744 FILE_ATTRIBUTE_NORMAL
,
745 NTCREATEX_SHARE_ACCESS_READ
|
746 NTCREATEX_SHARE_ACCESS_WRITE
|
747 NTCREATEX_SHARE_ACCESS_DELETE
,
748 NTCREATEX_DISP_OVERWRITE_IF
,
751 torture_assert(tctx
, fnum2
!= -1,
752 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
753 fname_new
, smbcli_errstr(cli1
->tree
)));
755 status
= smbcli_nt_delete_on_close(cli2
->tree
, fnum2
, true);
757 torture_assert_ntstatus_ok(tctx
, status
,
758 "setting delete_on_close on file failed !");
760 smbcli_close(cli2
->tree
, fnum2
);
762 /* The file should be around under the new name, there's a second
765 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname_new
, true, __location__
);
767 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
769 FILE_ATTRIBUTE_NORMAL
,
770 NTCREATEX_SHARE_ACCESS_READ
|
771 NTCREATEX_SHARE_ACCESS_WRITE
|
772 NTCREATEX_SHARE_ACCESS_DELETE
,
773 NTCREATEX_DISP_OVERWRITE_IF
,
776 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
777 fname
, smbcli_errstr(cli1
->tree
)));
779 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
781 smbcli_close(cli2
->tree
, fnum2
);
782 smbcli_close(cli1
->tree
, fnum1
);
784 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
786 FILE_ATTRIBUTE_NORMAL
,
787 NTCREATEX_SHARE_ACCESS_READ
|
788 NTCREATEX_SHARE_ACCESS_WRITE
|
789 NTCREATEX_SHARE_ACCESS_DELETE
,
793 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
794 fname
, smbcli_errstr(cli1
->tree
)));
796 smbcli_close(cli1
->tree
, fnum1
);
798 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname_new
, 0,
800 FILE_ATTRIBUTE_NORMAL
,
801 NTCREATEX_SHARE_ACCESS_READ
|
802 NTCREATEX_SHARE_ACCESS_WRITE
|
803 NTCREATEX_SHARE_ACCESS_DELETE
,
807 torture_assert(tctx
, fnum1
== -1,
808 "smbcli_open succeeded, should have "
815 static bool deltest16(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
821 del_clean_area(cli1
, cli2
);
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
);
831 /* Firstly create with all access, but delete on close. */
832 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
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);
841 torture_assert (tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
843 /* The delete on close bit is *not* reported as being set. */
844 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
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__
);
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
,
861 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
862 fname
, smbcli_errstr(cli1
->tree
)));
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__
);
869 smbcli_close(cli1
->tree
, fnum1
);
871 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
872 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, true, __location__
);
874 smbcli_close(cli2
->tree
, fnum2
);
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)",
881 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
887 static bool deltest16a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
893 del_clean_area(cli1
, cli2
);
897 /* Ensure the file doesn't already exist. */
898 smbcli_close(cli1
->tree
, fnum1
);
899 smbcli_close(cli1
->tree
, fnum2
);
900 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
901 smbcli_unlink(cli1
->tree
, fname
);
903 /* Firstly open and create with all access */
904 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
906 FILE_ATTRIBUTE_NORMAL
,
907 NTCREATEX_SHARE_ACCESS_READ
|
908 NTCREATEX_SHARE_ACCESS_WRITE
|
909 NTCREATEX_SHARE_ACCESS_DELETE
,
910 NTCREATEX_DISP_CREATE
,
912 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
913 fname
, smbcli_errstr(cli1
->tree
)));
915 /* And close - just to create the file. */
916 smbcli_close(cli1
->tree
, fnum1
);
918 /* Firstly create with all access, but delete on close. */
919 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
921 FILE_ATTRIBUTE_NORMAL
,
922 NTCREATEX_SHARE_ACCESS_READ
|
923 NTCREATEX_SHARE_ACCESS_WRITE
|
924 NTCREATEX_SHARE_ACCESS_DELETE
,
926 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
928 torture_assert (tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
930 /* The delete on close bit is *not* reported as being set. */
931 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
933 /* The delete on close bit is *not* reported as being set. */
934 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
935 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
937 /* Now try opening again for read-only. */
938 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
939 SEC_RIGHTS_FILE_READ
,
940 FILE_ATTRIBUTE_NORMAL
,
941 NTCREATEX_SHARE_ACCESS_READ
|
942 NTCREATEX_SHARE_ACCESS_WRITE
|
943 NTCREATEX_SHARE_ACCESS_DELETE
,
948 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
949 fname
, smbcli_errstr(cli1
->tree
)));
951 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
952 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
953 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
954 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
956 smbcli_close(cli1
->tree
, fnum1
);
958 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
959 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
961 smbcli_close(cli2
->tree
, fnum2
);
963 /* And the file should be deleted ! */
964 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
965 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
966 fname
, smbcli_errstr(cli1
->tree
)));
968 smbcli_close(cli1
->tree
, fnum1
);
969 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
970 smbcli_unlink(cli1
->tree
, fname
);
976 static bool deltest17(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
982 del_clean_area(cli1
, cli2
);
986 /* Ensure the file doesn't already exist. */
987 smbcli_close(cli1
->tree
, fnum1
);
988 smbcli_close(cli1
->tree
, fnum2
);
989 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
990 smbcli_unlink(cli1
->tree
, fname
);
992 /* Firstly open and create with all access */
993 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
995 FILE_ATTRIBUTE_NORMAL
,
996 NTCREATEX_SHARE_ACCESS_READ
|
997 NTCREATEX_SHARE_ACCESS_WRITE
|
998 NTCREATEX_SHARE_ACCESS_DELETE
,
999 NTCREATEX_DISP_CREATE
,
1001 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1002 fname
, smbcli_errstr(cli1
->tree
)));
1004 /* And close - just to create the file. */
1005 smbcli_close(cli1
->tree
, fnum1
);
1007 /* Next open with all access, but add delete on close. */
1008 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1009 SEC_RIGHTS_FILE_ALL
,
1010 FILE_ATTRIBUTE_NORMAL
,
1011 NTCREATEX_SHARE_ACCESS_READ
|
1012 NTCREATEX_SHARE_ACCESS_WRITE
|
1013 NTCREATEX_SHARE_ACCESS_DELETE
,
1014 NTCREATEX_DISP_OPEN
,
1015 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1017 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1018 fname
, smbcli_errstr(cli1
->tree
)));
1020 /* The delete on close bit is *not* reported as being set. */
1021 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1023 /* Now try opening again for read-only. */
1024 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1025 SEC_RIGHTS_FILE_READ
|
1027 FILE_ATTRIBUTE_NORMAL
,
1028 NTCREATEX_SHARE_ACCESS_READ
|
1029 NTCREATEX_SHARE_ACCESS_WRITE
|
1030 NTCREATEX_SHARE_ACCESS_DELETE
,
1031 NTCREATEX_DISP_OPEN
,
1035 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1036 fname
, smbcli_errstr(cli1
->tree
)));
1038 /* still not reported as being set on either */
1039 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1040 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1042 smbcli_close(cli1
->tree
, fnum1
);
1044 /* After the first close, the files has the delete on close bit set. */
1045 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1047 smbcli_close(cli1
->tree
, fnum2
);
1049 /* Make sure the file has been deleted */
1050 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1051 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s failed (should succeed) - %s",
1052 fname
, smbcli_errstr(cli1
->tree
)));
1054 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1059 /* Test 17a - like 17, but the delete on close handle is closed last */
1060 static bool deltest17a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1064 bool correct
= true;
1066 del_clean_area(cli1
, cli2
);
1068 /* Ensure the file doesn't already exist. */
1069 smbcli_close(cli1
->tree
, fnum1
);
1070 smbcli_close(cli1
->tree
, fnum2
);
1071 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1072 smbcli_unlink(cli1
->tree
, fname
);
1074 /* Firstly open and create with all access */
1075 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1076 SEC_RIGHTS_FILE_ALL
,
1077 FILE_ATTRIBUTE_NORMAL
,
1078 NTCREATEX_SHARE_ACCESS_READ
|
1079 NTCREATEX_SHARE_ACCESS_WRITE
|
1080 NTCREATEX_SHARE_ACCESS_DELETE
,
1081 NTCREATEX_DISP_CREATE
,
1083 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1084 fname
, smbcli_errstr(cli1
->tree
)));
1086 /* And close - just to create the file. */
1087 smbcli_close(cli1
->tree
, fnum1
);
1089 /* Next open with all access, but add delete on close. */
1090 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1091 SEC_RIGHTS_FILE_ALL
,
1092 FILE_ATTRIBUTE_NORMAL
,
1093 NTCREATEX_SHARE_ACCESS_READ
|
1094 NTCREATEX_SHARE_ACCESS_WRITE
|
1095 NTCREATEX_SHARE_ACCESS_DELETE
,
1096 NTCREATEX_DISP_OPEN
,
1097 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1099 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1100 fname
, smbcli_errstr(cli1
->tree
)));
1102 /* The delete on close bit is *not* reported as being set. */
1103 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1105 /* Now try opening again for read-only. */
1106 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1107 SEC_RIGHTS_FILE_READ
|
1109 FILE_ATTRIBUTE_NORMAL
,
1110 NTCREATEX_SHARE_ACCESS_READ
|
1111 NTCREATEX_SHARE_ACCESS_WRITE
|
1112 NTCREATEX_SHARE_ACCESS_DELETE
,
1113 NTCREATEX_DISP_OPEN
,
1117 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1118 fname
, smbcli_errstr(cli1
->tree
)));
1120 /* still not reported as being set on either */
1121 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1122 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1124 smbcli_close(cli1
->tree
, fnum2
);
1126 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1128 smbcli_close(cli1
->tree
, fnum1
);
1131 * The file is still there:
1132 * The second open seems to have removed the initial
1133 * delete on close flag from the first handle
1135 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1136 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1137 fname
, smbcli_errstr(cli1
->tree
)));
1139 smbcli_close(cli1
->tree
, fnum1
);
1140 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1141 smbcli_unlink(cli1
->tree
, fname
);
1146 /* Test 17b - like 17a, but the initial delete on close is set on the second handle */
1147 static bool deltest17b(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1151 bool correct
= true;
1153 del_clean_area(cli1
, cli2
);
1155 /* Ensure the file doesn't already exist. */
1156 smbcli_close(cli1
->tree
, fnum1
);
1157 smbcli_close(cli1
->tree
, fnum2
);
1158 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1159 smbcli_unlink(cli1
->tree
, fname
);
1161 /* Firstly open and create with all access */
1162 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1163 SEC_RIGHTS_FILE_ALL
,
1164 FILE_ATTRIBUTE_NORMAL
,
1165 NTCREATEX_SHARE_ACCESS_READ
|
1166 NTCREATEX_SHARE_ACCESS_WRITE
|
1167 NTCREATEX_SHARE_ACCESS_DELETE
,
1168 NTCREATEX_DISP_CREATE
,
1170 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1171 fname
, smbcli_errstr(cli1
->tree
)));
1173 /* And close - just to create the file. */
1174 smbcli_close(cli1
->tree
, fnum1
);
1176 /* Next open with all access, but add delete on close. */
1177 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1178 SEC_RIGHTS_FILE_ALL
,
1179 FILE_ATTRIBUTE_NORMAL
,
1180 NTCREATEX_SHARE_ACCESS_READ
|
1181 NTCREATEX_SHARE_ACCESS_WRITE
|
1182 NTCREATEX_SHARE_ACCESS_DELETE
,
1183 NTCREATEX_DISP_OPEN
,
1186 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1187 fname
, smbcli_errstr(cli1
->tree
)));
1189 /* The delete on close bit is *not* reported as being set. */
1190 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1192 /* Now try opening again for read-only. */
1193 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1194 SEC_RIGHTS_FILE_READ
|
1196 FILE_ATTRIBUTE_NORMAL
,
1197 NTCREATEX_SHARE_ACCESS_READ
|
1198 NTCREATEX_SHARE_ACCESS_WRITE
|
1199 NTCREATEX_SHARE_ACCESS_DELETE
,
1200 NTCREATEX_DISP_OPEN
,
1201 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1204 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1205 fname
, smbcli_errstr(cli1
->tree
)));
1207 /* still not reported as being set on either */
1208 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1209 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1211 smbcli_close(cli1
->tree
, fnum1
);
1213 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1215 smbcli_close(cli1
->tree
, fnum2
);
1217 /* Make sure the file has been deleted */
1218 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1219 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeeded (should fail)",
1222 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1227 /* Test 17c - like 17, but the initial delete on close is set on the second handle */
1228 static bool deltest17c(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1232 bool correct
= true;
1234 del_clean_area(cli1
, cli2
);
1236 /* Ensure the file doesn't already exist. */
1237 smbcli_close(cli1
->tree
, fnum1
);
1238 smbcli_close(cli1
->tree
, fnum2
);
1239 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1240 smbcli_unlink(cli1
->tree
, fname
);
1242 /* Firstly open and create with all access */
1243 fnum1
= smbcli_nt_create_full(cli1
->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_CREATE
,
1251 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1252 fname
, smbcli_errstr(cli1
->tree
)));
1254 /* And close - just to create the file. */
1255 smbcli_close(cli1
->tree
, fnum1
);
1257 /* Next open with all access, but add delete on close. */
1258 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1259 SEC_RIGHTS_FILE_ALL
,
1260 FILE_ATTRIBUTE_NORMAL
,
1261 NTCREATEX_SHARE_ACCESS_READ
|
1262 NTCREATEX_SHARE_ACCESS_WRITE
|
1263 NTCREATEX_SHARE_ACCESS_DELETE
,
1264 NTCREATEX_DISP_OPEN
,
1267 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1268 fname
, smbcli_errstr(cli1
->tree
)));
1270 /* The delete on close bit is *not* reported as being set. */
1271 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1273 /* Now try opening again for read-only. */
1274 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1275 SEC_RIGHTS_FILE_READ
|
1277 FILE_ATTRIBUTE_NORMAL
,
1278 NTCREATEX_SHARE_ACCESS_READ
|
1279 NTCREATEX_SHARE_ACCESS_WRITE
|
1280 NTCREATEX_SHARE_ACCESS_DELETE
,
1281 NTCREATEX_DISP_OPEN
,
1282 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1285 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1286 fname
, smbcli_errstr(cli1
->tree
)));
1288 /* still not reported as being set on either */
1289 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1290 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1292 smbcli_close(cli1
->tree
, fnum2
);
1294 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
1296 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1297 torture_assert(tctx
, fnum2
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeeded (should fail)",
1300 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1302 smbcli_close(cli1
->tree
, fnum1
);
1304 /* Make sure the file has been deleted */
1305 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1306 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1309 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1314 /* Test 17d - like 17a, but the first delete-on-close opener creates the file */
1315 static bool deltest17d(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1319 bool correct
= true;
1321 del_clean_area(cli1
, cli2
);
1323 /* Ensure the file doesn't already exist. */
1324 smbcli_close(cli1
->tree
, fnum1
);
1325 smbcli_close(cli1
->tree
, fnum2
);
1326 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1327 smbcli_unlink(cli1
->tree
, fname
);
1330 /* Create the file with delete on close. */
1331 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1332 SEC_RIGHTS_FILE_ALL
,
1333 FILE_ATTRIBUTE_NORMAL
,
1334 NTCREATEX_SHARE_ACCESS_READ
|
1335 NTCREATEX_SHARE_ACCESS_WRITE
|
1336 NTCREATEX_SHARE_ACCESS_DELETE
,
1337 NTCREATEX_DISP_CREATE
,
1338 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1340 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1341 fname
, smbcli_errstr(cli1
->tree
)));
1343 /* The delete on close bit is *not* reported as being set. */
1344 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1346 /* Now try opening again for read-only. */
1347 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1348 SEC_RIGHTS_FILE_READ
|
1350 FILE_ATTRIBUTE_NORMAL
,
1351 NTCREATEX_SHARE_ACCESS_READ
|
1352 NTCREATEX_SHARE_ACCESS_WRITE
|
1353 NTCREATEX_SHARE_ACCESS_DELETE
,
1354 NTCREATEX_DISP_OPEN
,
1358 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1359 fname
, smbcli_errstr(cli1
->tree
)));
1361 /* still not reported as being set on either */
1362 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1363 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1365 smbcli_close(cli1
->tree
, fnum2
);
1367 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1369 smbcli_close(cli1
->tree
, fnum1
);
1372 * The file is still there:
1373 * The second open seems to have removed the initial
1374 * delete on close flag from the first handle
1376 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1377 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeed (should fail)",
1380 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1385 static bool deltest17e(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1390 bool correct
= true;
1392 del_clean_area(cli1
, cli2
);
1394 /* Ensure the file doesn't already exist. */
1395 smbcli_close(cli1
->tree
, fnum1
);
1396 smbcli_close(cli1
->tree
, fnum2
);
1397 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1398 smbcli_unlink(cli1
->tree
, fname
);
1400 /* Firstly open and create with all access */
1401 fnum3
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1402 SEC_RIGHTS_FILE_ALL
,
1403 FILE_ATTRIBUTE_NORMAL
,
1404 NTCREATEX_SHARE_ACCESS_READ
|
1405 NTCREATEX_SHARE_ACCESS_WRITE
|
1406 NTCREATEX_SHARE_ACCESS_DELETE
,
1407 NTCREATEX_DISP_CREATE
,
1409 torture_assert(tctx
, fnum3
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1410 fname
, smbcli_errstr(cli1
->tree
)));
1412 /* Next open with all access, but add delete on close. */
1413 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1414 SEC_RIGHTS_FILE_ALL
,
1415 FILE_ATTRIBUTE_NORMAL
,
1416 NTCREATEX_SHARE_ACCESS_READ
|
1417 NTCREATEX_SHARE_ACCESS_WRITE
|
1418 NTCREATEX_SHARE_ACCESS_DELETE
,
1419 NTCREATEX_DISP_OPEN
,
1420 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1422 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1423 fname
, smbcli_errstr(cli1
->tree
)));
1425 /* The delete on close bit is *not* reported as being set. */
1426 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1427 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1429 /* Now try opening again for read-only. */
1430 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1431 SEC_RIGHTS_FILE_READ
|
1433 FILE_ATTRIBUTE_NORMAL
,
1434 NTCREATEX_SHARE_ACCESS_READ
|
1435 NTCREATEX_SHARE_ACCESS_WRITE
|
1436 NTCREATEX_SHARE_ACCESS_DELETE
,
1437 NTCREATEX_DISP_OPEN
,
1441 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1442 fname
, smbcli_errstr(cli1
->tree
)));
1444 /* still not reported as being set on either */
1445 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1446 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1447 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1449 smbcli_close(cli1
->tree
, fnum1
);
1452 * closing the handle that has delete_on_close set
1453 * inherits the flag to the global context
1455 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1456 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1458 smbcli_close(cli1
->tree
, fnum2
);
1460 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1462 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1463 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1466 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1468 smbcli_close(cli1
->tree
, fnum3
);
1470 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1471 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 5 of %s succeeded (should fail)",
1474 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1479 static bool deltest17f(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1484 bool correct
= true;
1487 del_clean_area(cli1
, cli2
);
1489 /* Ensure the file doesn't already exist. */
1490 smbcli_close(cli1
->tree
, fnum1
);
1491 smbcli_close(cli1
->tree
, fnum2
);
1492 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1493 smbcli_unlink(cli1
->tree
, fname
);
1495 /* Firstly open and create with all access */
1496 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1497 SEC_RIGHTS_FILE_ALL
,
1498 FILE_ATTRIBUTE_NORMAL
,
1499 NTCREATEX_SHARE_ACCESS_READ
|
1500 NTCREATEX_SHARE_ACCESS_WRITE
|
1501 NTCREATEX_SHARE_ACCESS_DELETE
,
1502 NTCREATEX_DISP_CREATE
,
1503 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1504 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1505 fname
, smbcli_errstr(cli1
->tree
)));
1507 /* The delete on close bit is *not* reported as being set. */
1508 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1510 /* Next open with all access, but add delete on close. */
1511 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1512 SEC_RIGHTS_FILE_ALL
,
1513 FILE_ATTRIBUTE_NORMAL
,
1514 NTCREATEX_SHARE_ACCESS_READ
|
1515 NTCREATEX_SHARE_ACCESS_WRITE
|
1516 NTCREATEX_SHARE_ACCESS_DELETE
,
1517 NTCREATEX_DISP_OPEN
,
1518 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1520 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1521 fname
, smbcli_errstr(cli1
->tree
)));
1523 /* still not reported as being set on either */
1524 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1525 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1527 /* Now try opening again for read-only. */
1528 fnum3
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1529 SEC_RIGHTS_FILE_READ
|
1531 FILE_ATTRIBUTE_NORMAL
,
1532 NTCREATEX_SHARE_ACCESS_READ
|
1533 NTCREATEX_SHARE_ACCESS_WRITE
|
1534 NTCREATEX_SHARE_ACCESS_DELETE
,
1535 NTCREATEX_DISP_OPEN
,
1536 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1539 torture_assert(tctx
, fnum3
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1540 fname
, smbcli_errstr(cli1
->tree
)));
1542 /* still not reported as being set on either */
1543 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1544 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1545 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1547 smbcli_close(cli1
->tree
, fnum1
);
1550 * closing the handle that has delete_on_close set
1551 * inherits the flag to the global context
1553 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1554 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1557 status
= smbcli_nt_delete_on_close(cli1
->tree
, fnum2
, false);
1558 torture_assert_ntstatus_ok(tctx
, status
,
1559 "clearing delete_on_close on file failed !");
1561 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1562 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1564 smbcli_close(cli1
->tree
, fnum2
);
1566 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1568 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1569 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1572 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1574 smbcli_close(cli1
->tree
, fnum3
);
1576 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1577 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 5 of %s succeeded (should fail)",
1580 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1586 static bool deltest18(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1590 bool correct
= true;
1592 del_clean_area(cli1
, cli2
);
1594 /* Test 18. With directories. */
1596 /* Ensure the file doesn't already exist. */
1597 smbcli_close(cli1
->tree
, fnum1
);
1598 smbcli_close(cli1
->tree
, fnum2
);
1600 smbcli_deltree(cli1
->tree
, dname
);
1602 /* Firstly create with all access, but delete on close. */
1603 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1605 SEC_FILE_WRITE_DATA
|
1607 FILE_ATTRIBUTE_DIRECTORY
,
1608 NTCREATEX_SHARE_ACCESS_READ
|
1609 NTCREATEX_SHARE_ACCESS_WRITE
|
1610 NTCREATEX_SHARE_ACCESS_DELETE
,
1611 NTCREATEX_DISP_CREATE
,
1612 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1614 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1615 dname
, smbcli_errstr(cli1
->tree
)));
1618 * The delete on close bit is *not* reported as being set.
1619 * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
1620 * close as being set. This causes the subsequent create to fail with
1621 * NT_STATUS_DELETE_PENDING.
1623 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1625 /* Now try opening again for read-only. */
1626 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1627 SEC_RIGHTS_FILE_READ
,
1628 FILE_ATTRIBUTE_DIRECTORY
,
1629 NTCREATEX_SHARE_ACCESS_READ
|
1630 NTCREATEX_SHARE_ACCESS_WRITE
|
1631 NTCREATEX_SHARE_ACCESS_DELETE
,
1632 NTCREATEX_DISP_OPEN
,
1633 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1637 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1638 dname
, smbcli_errstr(cli1
->tree
)));
1640 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1641 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, false, __location__
);
1643 smbcli_close(cli1
->tree
, fnum1
);
1645 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, true, __location__
);
1647 smbcli_close(cli1
->tree
, fnum2
);
1649 /* And the directory should be deleted ! */
1650 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1651 SEC_RIGHTS_FILE_READ
,
1652 FILE_ATTRIBUTE_DIRECTORY
,
1653 NTCREATEX_SHARE_ACCESS_READ
|
1654 NTCREATEX_SHARE_ACCESS_WRITE
|
1655 NTCREATEX_SHARE_ACCESS_DELETE
,
1656 NTCREATEX_DISP_OPEN
,
1657 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1658 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail)",
1665 static bool deltest19(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1669 bool correct
= true;
1671 del_clean_area(cli1
, cli2
);
1675 smbcli_deltree(cli1
->tree
, dname
);
1677 /* Firstly open and create with all access */
1678 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1680 SEC_FILE_WRITE_DATA
|
1682 FILE_ATTRIBUTE_DIRECTORY
,
1683 NTCREATEX_SHARE_ACCESS_READ
|
1684 NTCREATEX_SHARE_ACCESS_WRITE
|
1685 NTCREATEX_SHARE_ACCESS_DELETE
,
1686 NTCREATEX_DISP_CREATE
,
1687 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1689 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1690 dname
, smbcli_errstr(cli1
->tree
)));
1692 /* And close - just to create the directory. */
1693 smbcli_close(cli1
->tree
, fnum1
);
1695 /* Next open with all access, but add delete on close. */
1696 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1698 SEC_FILE_WRITE_DATA
|
1700 FILE_ATTRIBUTE_DIRECTORY
,
1701 NTCREATEX_SHARE_ACCESS_READ
|
1702 NTCREATEX_SHARE_ACCESS_WRITE
|
1703 NTCREATEX_SHARE_ACCESS_DELETE
,
1704 NTCREATEX_DISP_OPEN
,
1705 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1707 torture_assert(tctx
, fnum1
!= -1,
1708 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
1711 * The delete on close bit is *not* reported as being set.
1712 * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
1713 * close as being set. This causes the subsequent create to fail with
1714 * NT_STATUS_DELETE_PENDING.
1716 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1718 /* Now try opening again for read-only. */
1719 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1720 SEC_RIGHTS_FILE_READ
,
1721 FILE_ATTRIBUTE_DIRECTORY
,
1722 NTCREATEX_SHARE_ACCESS_READ
|
1723 NTCREATEX_SHARE_ACCESS_WRITE
|
1724 NTCREATEX_SHARE_ACCESS_DELETE
,
1725 NTCREATEX_DISP_OPEN
,
1726 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1729 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1730 dname
, smbcli_errstr(cli1
->tree
)));
1732 smbcli_close(cli1
->tree
, fnum1
);
1734 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, true, __location__
);
1736 smbcli_close(cli1
->tree
, fnum2
);
1738 /* See if the file is deleted - for a directory this seems to be true ! */
1739 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1740 SEC_RIGHTS_FILE_READ
,
1741 FILE_ATTRIBUTE_DIRECTORY
,
1742 NTCREATEX_SHARE_ACCESS_READ
|
1743 NTCREATEX_SHARE_ACCESS_WRITE
|
1744 NTCREATEX_SHARE_ACCESS_DELETE
,
1745 NTCREATEX_DISP_OPEN
,
1746 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1748 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1750 torture_assert(tctx
, fnum1
== -1,
1751 talloc_asprintf(tctx
, "open of %s succeeded (should fail)", dname
));
1757 static bool deltest20(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1761 bool correct
= true;
1764 del_clean_area(cli1
, cli2
);
1766 /* Test 20 -- non-empty directory hardest to get right... */
1768 if (torture_setting_bool(tctx
, "samba3", false)) {
1772 smbcli_deltree(cli1
->tree
, dname
);
1774 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1776 SEC_FILE_WRITE_DATA
|
1778 FILE_ATTRIBUTE_DIRECTORY
,
1779 NTCREATEX_SHARE_ACCESS_READ
|
1780 NTCREATEX_SHARE_ACCESS_WRITE
|
1781 NTCREATEX_SHARE_ACCESS_DELETE
,
1782 NTCREATEX_DISP_CREATE
,
1783 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1784 torture_assert(tctx
, dnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed: %s!",
1785 dname
, smbcli_errstr(cli1
->tree
)));
1787 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, false, __location__
);
1788 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
1792 asprintf(&fullname
, "\\%s%s", dname
, fname
);
1793 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1795 torture_assert(tctx
, fnum1
== -1,
1796 "smbcli_open succeeded, should have "
1797 "failed with NT_STATUS_DELETE_PENDING"
1800 torture_assert_ntstatus_equal(tctx
,
1801 smbcli_nt_error(cli1
->tree
),
1802 NT_STATUS_DELETE_PENDING
,
1803 "smbcli_open failed");
1806 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, false);
1807 torture_assert_ntstatus_ok(tctx
, status
,
1808 "setting delete_on_close on file failed !");
1812 asprintf(&fullname
, "\\%s%s", dname
, fname
);
1813 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1815 torture_assert(tctx
, fnum1
!= -1,
1816 talloc_asprintf(tctx
, "smbcli_open failed: %s\n",
1817 smbcli_errstr(cli1
->tree
)));
1818 smbcli_close(cli1
->tree
, fnum1
);
1821 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
1823 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_DIRECTORY_NOT_EMPTY
,
1824 "setting delete_on_close failed");
1825 smbcli_close(cli1
->tree
, dnum1
);
1831 static bool deltest20a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1835 bool correct
= true;
1837 del_clean_area(cli1
, cli2
);
1841 /* Ensure the file doesn't already exist. */
1842 smbcli_close(cli1
->tree
, fnum1
);
1843 smbcli_close(cli1
->tree
, fnum2
);
1844 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1845 smbcli_unlink(cli1
->tree
, fname
);
1847 /* Firstly open and create with all access */
1848 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1849 SEC_RIGHTS_FILE_ALL
,
1850 FILE_ATTRIBUTE_NORMAL
,
1851 NTCREATEX_SHARE_ACCESS_READ
|
1852 NTCREATEX_SHARE_ACCESS_WRITE
|
1853 NTCREATEX_SHARE_ACCESS_DELETE
,
1854 NTCREATEX_DISP_CREATE
,
1856 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1857 fname
, smbcli_errstr(cli1
->tree
)));
1859 /* Next open with all access, but add delete on close. */
1860 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1861 SEC_RIGHTS_FILE_ALL
,
1862 FILE_ATTRIBUTE_NORMAL
,
1863 NTCREATEX_SHARE_ACCESS_READ
|
1864 NTCREATEX_SHARE_ACCESS_WRITE
|
1865 NTCREATEX_SHARE_ACCESS_DELETE
,
1866 NTCREATEX_DISP_OPEN
,
1867 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1869 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1870 fname
, smbcli_errstr(cli2
->tree
)));
1872 /* The delete on close bit is *not* reported as being set. */
1873 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1874 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1876 smbcli_close(cli1
->tree
, fnum1
);
1878 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1880 smbcli_close(cli2
->tree
, fnum2
);
1882 /* See if the file is deleted - should be.... */
1883 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1884 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
1885 fname
, smbcli_errstr(cli1
->tree
)));
1891 /* This is the delete semantics that the cifsfs client depends on when
1892 * trying to delete an open file on a Windows server. It
1893 * opens a file with initial delete on close set, renames it then closes
1894 * all open handles. The file goes away on Windows.
1897 static bool deltest20b(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1901 bool correct
= true;
1903 del_clean_area(cli1
, cli2
);
1907 /* Ensure the file doesn't already exist. */
1908 smbcli_close(cli1
->tree
, fnum1
);
1909 smbcli_close(cli1
->tree
, fnum2
);
1910 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1911 smbcli_unlink(cli1
->tree
, fname
);
1912 smbcli_setatr(cli1
->tree
, fname_new
, 0, 0);
1913 smbcli_unlink(cli1
->tree
, fname_new
);
1915 /* Firstly open and create with all access */
1916 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1917 SEC_RIGHTS_FILE_ALL
,
1918 FILE_ATTRIBUTE_NORMAL
,
1919 NTCREATEX_SHARE_ACCESS_READ
|
1920 NTCREATEX_SHARE_ACCESS_WRITE
|
1921 NTCREATEX_SHARE_ACCESS_DELETE
,
1922 NTCREATEX_DISP_CREATE
,
1924 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1925 fname
, smbcli_errstr(cli1
->tree
)));
1927 /* And close - just to create the file. */
1928 smbcli_close(cli1
->tree
, fnum1
);
1930 /* Firstly open and create with all access */
1931 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1932 SEC_RIGHTS_FILE_ALL
,
1933 FILE_ATTRIBUTE_NORMAL
,
1934 NTCREATEX_SHARE_ACCESS_READ
|
1935 NTCREATEX_SHARE_ACCESS_WRITE
|
1936 NTCREATEX_SHARE_ACCESS_DELETE
,
1937 NTCREATEX_DISP_OPEN
,
1939 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1940 fname
, smbcli_errstr(cli1
->tree
)));
1942 /* Next open with all access, but add delete on close. */
1943 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1944 SEC_RIGHTS_FILE_ALL
,
1945 FILE_ATTRIBUTE_NORMAL
,
1946 NTCREATEX_SHARE_ACCESS_READ
|
1947 NTCREATEX_SHARE_ACCESS_WRITE
|
1948 NTCREATEX_SHARE_ACCESS_DELETE
,
1949 NTCREATEX_DISP_OPEN
,
1950 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1952 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1953 fname
, smbcli_errstr(cli2
->tree
)));
1955 /* The delete on close bit is *not* reported as being set. */
1956 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1957 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1959 smbcli_close(cli1
->tree
, fnum1
);
1961 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1963 /* Rename the file by handle. */
1966 union smb_setfileinfo sfinfo
;
1969 memset(&sfinfo
, '\0', sizeof(sfinfo
));
1970 sfinfo
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
1971 sfinfo
.generic
.in
.file
.fnum
= fnum2
;
1972 sfinfo
.rename_information
.in
.root_fid
= 0;
1973 /* Don't start the filename with '\\', we get NT_STATUS_NOT_SUPPORTED if so. */
1974 sfinfo
.rename_information
.in
.new_name
= fname_new
+ 1;
1975 sfinfo
.rename_information
.in
.overwrite
= 1;
1977 status
= smb_raw_setfileinfo(cli2
->tree
, &sfinfo
);
1979 torture_assert_ntstatus_equal(tctx
,status
,NT_STATUS_OK
,talloc_asprintf(tctx
, "rename of %s to %s failed (%s)",
1980 fname
, fname_new
, smbcli_errstr(cli2
->tree
)));
1983 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname_new
, false, __location__
);
1985 smbcli_close(cli2
->tree
, fnum2
);
1987 /* See if the file is deleted - should be.... */
1988 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1989 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
1990 fname
, smbcli_errstr(cli1
->tree
)));
1991 fnum1
= smbcli_open(cli1
->tree
, fname_new
, O_RDWR
, DENY_NONE
);
1992 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
1993 fname_new
, smbcli_errstr(cli1
->tree
)));
2000 static bool deltest21(struct torture_context
*tctx
)
2003 struct smbcli_state
*cli1
;
2004 struct smbcli_state
*cli2
;
2005 bool correct
= true;
2007 if (!torture_open_connection(&cli1
, tctx
, 0))
2010 if (!torture_open_connection(&cli2
, tctx
, 1))
2013 del_clean_area(cli1
, cli2
);
2015 /* Test 21 -- Test removal of file after socket close. */
2017 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2018 SEC_RIGHTS_FILE_ALL
,
2019 FILE_ATTRIBUTE_NORMAL
, NTCREATEX_SHARE_ACCESS_NONE
,
2020 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
2022 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
2023 fname
, smbcli_errstr(cli1
->tree
)));
2025 torture_assert_ntstatus_ok(tctx
,
2026 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true),
2027 talloc_asprintf(tctx
, "setting delete_on_close failed (%s)",
2028 smbcli_errstr(cli1
->tree
)));
2030 /* Ensure delete on close is set. */
2031 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
2033 /* Now yank the rug from under cli1. */
2034 smbcli_transport_dead(cli1
->transport
, NT_STATUS_LOCAL_DISCONNECT
);
2038 if (!torture_open_connection(&cli1
, tctx
, 0)) {
2042 /* On slow build farm machines it might happen that they are not fast
2043 * enogh to delete the file for this test */
2046 /* File should not be there. */
2047 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2048 SEC_RIGHTS_FILE_READ
,
2049 FILE_ATTRIBUTE_NORMAL
,
2050 NTCREATEX_SHARE_ACCESS_READ
|
2051 NTCREATEX_SHARE_ACCESS_WRITE
|
2052 NTCREATEX_SHARE_ACCESS_DELETE
,
2053 NTCREATEX_DISP_OPEN
,
2056 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2064 * Test whether a second *directory* handle inhibits delete if the first has
2065 * del-on-close set and is closed
2067 static bool deltest22(struct torture_context
*tctx
)
2071 struct smbcli_state
*cli1
;
2072 bool correct
= true;
2074 if (!torture_open_connection(&cli1
, tctx
, 0))
2077 smbcli_deltree(cli1
->tree
, dname
);
2079 torture_assert_ntstatus_ok(
2080 tctx
, smbcli_mkdir(cli1
->tree
, dname
),
2081 talloc_asprintf(tctx
, "smbcli_mdir failed: (%s)\n",
2082 smbcli_errstr(cli1
->tree
)));
2084 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2086 SEC_FILE_WRITE_DATA
|
2088 FILE_ATTRIBUTE_DIRECTORY
,
2089 NTCREATEX_SHARE_ACCESS_READ
|
2090 NTCREATEX_SHARE_ACCESS_WRITE
|
2091 NTCREATEX_SHARE_ACCESS_DELETE
,
2092 NTCREATEX_DISP_OPEN
,
2093 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2095 torture_assert(tctx
, dnum1
!= -1,
2096 talloc_asprintf(tctx
, "open of %s failed: %s!",
2097 dname
, smbcli_errstr(cli1
->tree
)));
2099 dnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2101 SEC_FILE_WRITE_DATA
,
2102 FILE_ATTRIBUTE_DIRECTORY
,
2103 NTCREATEX_SHARE_ACCESS_READ
|
2104 NTCREATEX_SHARE_ACCESS_WRITE
|
2105 NTCREATEX_SHARE_ACCESS_DELETE
,
2106 NTCREATEX_DISP_OPEN
,
2107 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2109 torture_assert(tctx
, dnum2
!= -1,
2110 talloc_asprintf(tctx
, "open of %s failed: %s!",
2111 dname
, smbcli_errstr(cli1
->tree
)));
2113 torture_assert_ntstatus_ok(
2114 tctx
, smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true),
2115 talloc_asprintf(tctx
, "setting delete_on_close failed (%s)",
2116 smbcli_errstr(cli1
->tree
)));
2118 smbcli_close(cli1
->tree
, dnum1
);
2120 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2122 SEC_FILE_WRITE_DATA
|
2124 FILE_ATTRIBUTE_DIRECTORY
,
2125 NTCREATEX_SHARE_ACCESS_READ
|
2126 NTCREATEX_SHARE_ACCESS_WRITE
|
2127 NTCREATEX_SHARE_ACCESS_DELETE
,
2128 NTCREATEX_DISP_OPEN
,
2129 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2131 torture_assert(tctx
, dnum1
== -1,
2132 talloc_asprintf(tctx
, "open of %s succeeded!\n",
2135 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
2137 smbcli_close(cli1
->tree
, dnum2
);
2138 CHECK_STATUS(cli1
, NT_STATUS_OK
);
2143 /* Test 23 - Second directory open fails when delete is pending. */
2144 static bool deltest23(struct torture_context
*tctx
,
2145 struct smbcli_state
*cli1
,
2146 struct smbcli_state
*cli2
)
2150 bool correct
= true;
2152 del_clean_area(cli1
, cli2
);
2154 /* Test 23 -- Basic delete on close for directories. */
2156 /* Open a directory */
2157 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2159 SEC_FILE_WRITE_DATA
|
2161 FILE_ATTRIBUTE_DIRECTORY
,
2162 NTCREATEX_SHARE_ACCESS_READ
|
2163 NTCREATEX_SHARE_ACCESS_WRITE
|
2164 NTCREATEX_SHARE_ACCESS_DELETE
,
2165 NTCREATEX_DISP_CREATE
,
2166 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2168 torture_assert(tctx
, dnum1
!= -1, talloc_asprintf(tctx
,
2169 "open of %s failed: %s!",
2170 dname
, smbcli_errstr(cli1
->tree
)));
2172 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, false,
2175 /* Set delete on close */
2176 (void)smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
2178 /* Attempt opening the directory again. It should fail. */
2179 dnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2181 SEC_FILE_WRITE_DATA
|
2183 FILE_ATTRIBUTE_DIRECTORY
,
2184 NTCREATEX_SHARE_ACCESS_READ
|
2185 NTCREATEX_SHARE_ACCESS_WRITE
|
2186 NTCREATEX_SHARE_ACCESS_DELETE
,
2187 NTCREATEX_DISP_OPEN
,
2188 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2190 torture_assert(tctx
, dnum2
== -1, talloc_asprintf(tctx
,
2191 "open of %s succeeded: %s. It should have failed "
2192 "with NT_STATUS_DELETE_PENDING",
2193 dname
, smbcli_errstr(cli1
->tree
)));
2195 torture_assert_ntstatus_equal(tctx
, smbcli_nt_error(cli1
->tree
),
2196 NT_STATUS_DELETE_PENDING
, "smbcli_open failed");
2202 Test delete on close semantics.
2204 struct torture_suite
*torture_test_delete(void)
2206 struct torture_suite
*suite
= torture_suite_create(
2207 talloc_autofree_context(), "delete");
2209 torture_suite_add_2smb_test(suite
, "deltest1", deltest1
);
2210 torture_suite_add_2smb_test(suite
, "deltest2", deltest2
);
2211 torture_suite_add_2smb_test(suite
, "deltest3", deltest3
);
2212 torture_suite_add_2smb_test(suite
, "deltest4", deltest4
);
2213 torture_suite_add_2smb_test(suite
, "deltest5", deltest5
);
2214 torture_suite_add_2smb_test(suite
, "deltest6", deltest6
);
2215 torture_suite_add_2smb_test(suite
, "deltest7", deltest7
);
2216 torture_suite_add_2smb_test(suite
, "deltest8", deltest8
);
2217 torture_suite_add_2smb_test(suite
, "deltest9", deltest9
);
2218 torture_suite_add_2smb_test(suite
, "deltest10", deltest10
);
2219 torture_suite_add_2smb_test(suite
, "deltest11", deltest11
);
2220 torture_suite_add_2smb_test(suite
, "deltest12", deltest12
);
2221 torture_suite_add_2smb_test(suite
, "deltest13", deltest13
);
2222 torture_suite_add_2smb_test(suite
, "deltest14", deltest14
);
2223 torture_suite_add_2smb_test(suite
, "deltest15", deltest15
);
2224 torture_suite_add_2smb_test(suite
, "deltest16", deltest16
);
2225 torture_suite_add_2smb_test(suite
, "deltest16a", deltest16a
);
2226 torture_suite_add_2smb_test(suite
, "deltest17", deltest17
);
2227 torture_suite_add_2smb_test(suite
, "deltest17a", deltest17a
);
2228 torture_suite_add_2smb_test(suite
, "deltest17b", deltest17b
);
2229 torture_suite_add_2smb_test(suite
, "deltest17c", deltest17c
);
2230 torture_suite_add_2smb_test(suite
, "deltest17d", deltest17d
);
2231 torture_suite_add_2smb_test(suite
, "deltest17e", deltest17e
);
2232 torture_suite_add_2smb_test(suite
, "deltest17f", deltest17f
);
2233 torture_suite_add_2smb_test(suite
, "deltest18", deltest18
);
2234 torture_suite_add_2smb_test(suite
, "deltest19", deltest19
);
2235 torture_suite_add_2smb_test(suite
, "deltest20", deltest20
);
2236 torture_suite_add_2smb_test(suite
, "deltest20a", deltest20a
);
2237 torture_suite_add_2smb_test(suite
, "deltest20b", deltest20b
);
2238 torture_suite_add_simple_test(suite
, "deltest21", deltest21
);
2239 torture_suite_add_simple_test(suite
, "deltest22", deltest22
);
2240 torture_suite_add_2smb_test(suite
, "deltest23", deltest23
);