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
)
481 del_clean_area(cli1
, cli2
);
483 /* This should fail - we need to set DELETE_ACCESS. */
486 * A file or directory create with DELETE_ON_CLOSE but
487 * without DELETE_ACCESS should fail with
488 * NT_STATUS_INVALID_PARAMETER.
491 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
492 SEC_FILE_READ_DATA
|SEC_FILE_WRITE_DATA
,
493 FILE_ATTRIBUTE_NORMAL
,
494 NTCREATEX_SHARE_ACCESS_NONE
,
495 NTCREATEX_DISP_OVERWRITE_IF
,
496 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
498 torture_assert(tctx
, fnum1
== -1,
499 talloc_asprintf(tctx
, "open of %s succeeded should have failed!",
502 /* Must fail with NT_STATUS_INVALID_PARAMETER. */
503 status
= smbcli_nt_error(cli1
->tree
);
504 torture_assert_ntstatus_equal(tctx
,
506 NT_STATUS_INVALID_PARAMETER
,
507 talloc_asprintf(tctx
, "create of %s should return "
508 "NT_STATUS_INVALID_PARAMETER, got %s",
510 smbcli_errstr(cli1
->tree
)));
512 /* This should fail - the file should not have been created. */
513 status
= smbcli_getatr(cli1
->tree
, fname
, NULL
, NULL
, NULL
);
514 torture_assert_ntstatus_equal(tctx
,
516 NT_STATUS_OBJECT_NAME_NOT_FOUND
,
517 talloc_asprintf(tctx
, "getattr of %s succeeded should "
518 "not have been created !",
525 static bool deltest10(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
529 del_clean_area(cli1
, cli2
);
531 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
535 FILE_ATTRIBUTE_NORMAL
,
536 NTCREATEX_SHARE_ACCESS_NONE
,
537 NTCREATEX_DISP_OVERWRITE_IF
,
538 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
539 torture_assert(tctx
, fnum1
!= -1,
540 talloc_asprintf(tctx
, "open of %s failed (%s)",
541 fname
, smbcli_errstr(cli1
->tree
)));
543 /* This should delete the file. */
544 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
545 talloc_asprintf(tctx
, "close failed (%s)",
546 smbcli_errstr(cli1
->tree
)));
548 /* This should fail.. */
549 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
550 torture_assert(tctx
, fnum1
== -1,
551 talloc_asprintf(tctx
, "open of %s succeeded should have been deleted on close !",
557 static bool deltest11(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
562 del_clean_area(cli1
, cli2
);
564 /* test 11 - does having read only attribute still allow delete on close. */
566 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
568 FILE_ATTRIBUTE_READONLY
,
569 NTCREATEX_SHARE_ACCESS_NONE
,
570 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
572 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
573 fname
, smbcli_errstr(cli1
->tree
)));
575 status
= smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true);
577 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_CANNOT_DELETE
,
578 talloc_asprintf(tctx
, "setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)", smbcli_errstr(cli1
->tree
)));
580 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
581 talloc_asprintf(tctx
, "close failed (%s)",
582 smbcli_errstr(cli1
->tree
)));
588 static bool deltest12(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
593 del_clean_area(cli1
, cli2
);
595 /* test 12 - does having read only attribute still allow delete on
596 * close at time of open. */
598 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
600 FILE_ATTRIBUTE_READONLY
,
601 NTCREATEX_SHARE_ACCESS_DELETE
,
602 NTCREATEX_DISP_OVERWRITE_IF
,
603 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
605 torture_assert(tctx
, fnum1
== -1,
606 talloc_asprintf(tctx
, "open of %s succeeded. Should fail with "
607 "NT_STATUS_CANNOT_DELETE.\n", fname
));
609 status
= smbcli_nt_error(cli1
->tree
);
610 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_CANNOT_DELETE
,
611 talloc_asprintf(tctx
, "setting delete_on_close on open should "
612 "fail with NT_STATUS_CANNOT_DELETE. Got %s "
614 smbcli_errstr(cli1
->tree
)));
620 static bool deltest13(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
626 del_clean_area(cli1
, cli2
);
628 /* Test 13: Does resetting the delete on close flag affect a second
631 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
635 FILE_ATTRIBUTE_NORMAL
,
636 NTCREATEX_SHARE_ACCESS_READ
|
637 NTCREATEX_SHARE_ACCESS_WRITE
|
638 NTCREATEX_SHARE_ACCESS_DELETE
,
639 NTCREATEX_DISP_OVERWRITE_IF
,
642 torture_assert(tctx
, fnum1
!= -1,
643 talloc_asprintf(tctx
, "open of %s failed (%s)",
644 fname
, smbcli_errstr(cli1
->tree
)));
646 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
650 FILE_ATTRIBUTE_NORMAL
,
651 NTCREATEX_SHARE_ACCESS_READ
|
652 NTCREATEX_SHARE_ACCESS_WRITE
|
653 NTCREATEX_SHARE_ACCESS_DELETE
,
654 NTCREATEX_DISP_OPEN
, 0, 0);
656 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
,
657 "open of %s failed (%s)",
658 fname
, smbcli_errstr(cli2
->tree
)));
660 torture_assert_ntstatus_ok(tctx
,
661 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
,
663 "setting delete_on_close on file failed !");
665 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
666 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
668 torture_assert_ntstatus_ok(tctx
, smbcli_nt_delete_on_close(cli2
->tree
, fnum2
,
670 "unsetting delete_on_close on file failed !");
672 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
673 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
675 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli1
->tree
, fnum1
),
676 talloc_asprintf(tctx
, "close - 1 failed (%s)",
677 smbcli_errstr(cli1
->tree
)));
679 torture_assert_ntstatus_ok(tctx
, smbcli_close(cli2
->tree
, fnum2
),
680 talloc_asprintf(tctx
, "close - 2 failed (%s)",
681 smbcli_errstr(cli2
->tree
)));
683 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDONLY
, DENY_NONE
);
685 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed!",
688 smbcli_close(cli1
->tree
, fnum1
);
694 static bool deltest14(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
699 del_clean_area(cli1
, cli2
);
701 /* Test 14 -- directory */
703 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
707 FILE_ATTRIBUTE_DIRECTORY
,
708 NTCREATEX_SHARE_ACCESS_READ
|
709 NTCREATEX_SHARE_ACCESS_WRITE
|
710 NTCREATEX_SHARE_ACCESS_DELETE
,
711 NTCREATEX_DISP_CREATE
, 0, 0);
712 torture_assert(tctx
, dnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed: %s!",
713 dname
, smbcli_errstr(cli1
->tree
)));
715 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, false, __location__
);
716 torture_assert_ntstatus_ok(tctx
, smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true),
717 "setting delete_on_close on file failed !");
718 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, true, __location__
);
719 smbcli_close(cli1
->tree
, dnum1
);
721 /* Now it should be gone... */
723 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
727 FILE_ATTRIBUTE_DIRECTORY
,
728 NTCREATEX_SHARE_ACCESS_READ
|
729 NTCREATEX_SHARE_ACCESS_WRITE
|
730 NTCREATEX_SHARE_ACCESS_DELETE
,
731 NTCREATEX_DISP_OPEN
, 0, 0);
732 torture_assert(tctx
, dnum1
== -1, "setting delete_on_close on file succeeded !");
738 static bool deltest15(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
745 del_clean_area(cli1
, cli2
);
747 /* Test 15: delete on close under rename */
749 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
750 smbcli_unlink(cli1
->tree
, fname
);
751 smbcli_unlink(cli1
->tree
, fname_new
);
753 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
755 FILE_ATTRIBUTE_NORMAL
,
756 NTCREATEX_SHARE_ACCESS_READ
|
757 NTCREATEX_SHARE_ACCESS_WRITE
|
758 NTCREATEX_SHARE_ACCESS_DELETE
,
759 NTCREATEX_DISP_OVERWRITE_IF
,
762 torture_assert(tctx
, fnum1
!= -1,
763 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
765 status
= smbcli_rename(cli2
->tree
, fname
, fname_new
);
767 torture_assert_ntstatus_ok(tctx
, status
, "renaming failed!");
769 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname_new
, 0,
771 FILE_ATTRIBUTE_NORMAL
,
772 NTCREATEX_SHARE_ACCESS_READ
|
773 NTCREATEX_SHARE_ACCESS_WRITE
|
774 NTCREATEX_SHARE_ACCESS_DELETE
,
775 NTCREATEX_DISP_OVERWRITE_IF
,
778 torture_assert(tctx
, fnum2
!= -1,
779 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
780 fname_new
, smbcli_errstr(cli1
->tree
)));
782 status
= smbcli_nt_delete_on_close(cli2
->tree
, fnum2
, true);
784 torture_assert_ntstatus_ok(tctx
, status
,
785 "setting delete_on_close on file failed !");
787 smbcli_close(cli2
->tree
, fnum2
);
789 /* The file should be around under the new name, there's a second
792 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname_new
, true, __location__
);
794 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
796 FILE_ATTRIBUTE_NORMAL
,
797 NTCREATEX_SHARE_ACCESS_READ
|
798 NTCREATEX_SHARE_ACCESS_WRITE
|
799 NTCREATEX_SHARE_ACCESS_DELETE
,
800 NTCREATEX_DISP_OVERWRITE_IF
,
803 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
804 fname
, smbcli_errstr(cli1
->tree
)));
806 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
808 smbcli_close(cli2
->tree
, fnum2
);
809 smbcli_close(cli1
->tree
, fnum1
);
811 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
813 FILE_ATTRIBUTE_NORMAL
,
814 NTCREATEX_SHARE_ACCESS_READ
|
815 NTCREATEX_SHARE_ACCESS_WRITE
|
816 NTCREATEX_SHARE_ACCESS_DELETE
,
820 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
821 fname
, smbcli_errstr(cli1
->tree
)));
823 smbcli_close(cli1
->tree
, fnum1
);
825 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname_new
, 0,
827 FILE_ATTRIBUTE_NORMAL
,
828 NTCREATEX_SHARE_ACCESS_READ
|
829 NTCREATEX_SHARE_ACCESS_WRITE
|
830 NTCREATEX_SHARE_ACCESS_DELETE
,
834 torture_assert(tctx
, fnum1
== -1,
835 "smbcli_open succeeded, should have "
842 static bool deltest16(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
848 del_clean_area(cli1
, cli2
);
852 /* Ensure the file doesn't already exist. */
853 smbcli_close(cli1
->tree
, fnum1
);
854 smbcli_close(cli1
->tree
, fnum2
);
855 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
856 smbcli_unlink(cli1
->tree
, fname
);
858 /* Firstly create with all access, but delete on close. */
859 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
861 FILE_ATTRIBUTE_NORMAL
,
862 NTCREATEX_SHARE_ACCESS_READ
|
863 NTCREATEX_SHARE_ACCESS_WRITE
|
864 NTCREATEX_SHARE_ACCESS_DELETE
,
865 NTCREATEX_DISP_CREATE
,
866 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
868 torture_assert (tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
870 /* The delete on close bit is *not* reported as being set. */
871 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
873 /* The delete on close bit is *not* reported as being set. */
874 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
875 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
877 /* Now try opening again for read-only. */
878 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
879 SEC_RIGHTS_FILE_READ
,
880 FILE_ATTRIBUTE_NORMAL
,
881 NTCREATEX_SHARE_ACCESS_READ
|
882 NTCREATEX_SHARE_ACCESS_WRITE
|
883 NTCREATEX_SHARE_ACCESS_DELETE
,
888 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
889 fname
, smbcli_errstr(cli1
->tree
)));
891 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
892 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
893 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
894 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
896 smbcli_close(cli1
->tree
, fnum1
);
898 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, true, __location__
);
899 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, true, __location__
);
901 smbcli_close(cli2
->tree
, fnum2
);
903 /* And the file should be deleted ! */
904 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
905 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail)",
908 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
914 static bool deltest16a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
920 del_clean_area(cli1
, cli2
);
924 /* Ensure the file doesn't already exist. */
925 smbcli_close(cli1
->tree
, fnum1
);
926 smbcli_close(cli1
->tree
, fnum2
);
927 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
928 smbcli_unlink(cli1
->tree
, fname
);
930 /* Firstly open and create with all access */
931 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
933 FILE_ATTRIBUTE_NORMAL
,
934 NTCREATEX_SHARE_ACCESS_READ
|
935 NTCREATEX_SHARE_ACCESS_WRITE
|
936 NTCREATEX_SHARE_ACCESS_DELETE
,
937 NTCREATEX_DISP_CREATE
,
939 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
940 fname
, smbcli_errstr(cli1
->tree
)));
942 /* And close - just to create the file. */
943 smbcli_close(cli1
->tree
, fnum1
);
945 /* Firstly create with all access, but delete on close. */
946 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
948 FILE_ATTRIBUTE_NORMAL
,
949 NTCREATEX_SHARE_ACCESS_READ
|
950 NTCREATEX_SHARE_ACCESS_WRITE
|
951 NTCREATEX_SHARE_ACCESS_DELETE
,
953 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
955 torture_assert (tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
957 /* The delete on close bit is *not* reported as being set. */
958 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
960 /* The delete on close bit is *not* reported as being set. */
961 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
962 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
964 /* Now try opening again for read-only. */
965 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
966 SEC_RIGHTS_FILE_READ
,
967 FILE_ATTRIBUTE_NORMAL
,
968 NTCREATEX_SHARE_ACCESS_READ
|
969 NTCREATEX_SHARE_ACCESS_WRITE
|
970 NTCREATEX_SHARE_ACCESS_DELETE
,
975 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
976 fname
, smbcli_errstr(cli1
->tree
)));
978 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
979 correct
&= check_delete_on_close(tctx
, cli1
, -1, fname
, false, __location__
);
980 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
981 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
983 smbcli_close(cli1
->tree
, fnum1
);
985 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
986 correct
&= check_delete_on_close(tctx
, cli2
, -1, fname
, false, __location__
);
988 smbcli_close(cli2
->tree
, fnum2
);
990 /* And the file should be deleted ! */
991 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
992 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
993 fname
, smbcli_errstr(cli1
->tree
)));
995 smbcli_close(cli1
->tree
, fnum1
);
996 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
997 smbcli_unlink(cli1
->tree
, fname
);
1003 static bool deltest17(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1007 bool correct
= true;
1009 del_clean_area(cli1
, cli2
);
1013 /* Ensure the file doesn't already exist. */
1014 smbcli_close(cli1
->tree
, fnum1
);
1015 smbcli_close(cli1
->tree
, fnum2
);
1016 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1017 smbcli_unlink(cli1
->tree
, fname
);
1019 /* Firstly open and create with all access */
1020 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1021 SEC_RIGHTS_FILE_ALL
,
1022 FILE_ATTRIBUTE_NORMAL
,
1023 NTCREATEX_SHARE_ACCESS_READ
|
1024 NTCREATEX_SHARE_ACCESS_WRITE
|
1025 NTCREATEX_SHARE_ACCESS_DELETE
,
1026 NTCREATEX_DISP_CREATE
,
1028 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1029 fname
, smbcli_errstr(cli1
->tree
)));
1031 /* And close - just to create the file. */
1032 smbcli_close(cli1
->tree
, fnum1
);
1034 /* Next open with all access, but add delete on close. */
1035 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1036 SEC_RIGHTS_FILE_ALL
,
1037 FILE_ATTRIBUTE_NORMAL
,
1038 NTCREATEX_SHARE_ACCESS_READ
|
1039 NTCREATEX_SHARE_ACCESS_WRITE
|
1040 NTCREATEX_SHARE_ACCESS_DELETE
,
1041 NTCREATEX_DISP_OPEN
,
1042 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1044 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1045 fname
, smbcli_errstr(cli1
->tree
)));
1047 /* The delete on close bit is *not* reported as being set. */
1048 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1050 /* Now try opening again for read-only. */
1051 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1052 SEC_RIGHTS_FILE_READ
|
1054 FILE_ATTRIBUTE_NORMAL
,
1055 NTCREATEX_SHARE_ACCESS_READ
|
1056 NTCREATEX_SHARE_ACCESS_WRITE
|
1057 NTCREATEX_SHARE_ACCESS_DELETE
,
1058 NTCREATEX_DISP_OPEN
,
1062 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1063 fname
, smbcli_errstr(cli1
->tree
)));
1065 /* still not reported as being set on either */
1066 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1067 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1069 smbcli_close(cli1
->tree
, fnum1
);
1071 /* After the first close, the files has the delete on close bit set. */
1072 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1074 smbcli_close(cli1
->tree
, fnum2
);
1076 /* Make sure the file has been deleted */
1077 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1078 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s failed (should succeed) - %s",
1079 fname
, smbcli_errstr(cli1
->tree
)));
1081 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1086 /* Test 17a - like 17, but the delete on close handle is closed last */
1087 static bool deltest17a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1091 bool correct
= true;
1093 del_clean_area(cli1
, cli2
);
1095 /* Ensure the file doesn't already exist. */
1096 smbcli_close(cli1
->tree
, fnum1
);
1097 smbcli_close(cli1
->tree
, fnum2
);
1098 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1099 smbcli_unlink(cli1
->tree
, fname
);
1101 /* Firstly open and create with all access */
1102 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1103 SEC_RIGHTS_FILE_ALL
,
1104 FILE_ATTRIBUTE_NORMAL
,
1105 NTCREATEX_SHARE_ACCESS_READ
|
1106 NTCREATEX_SHARE_ACCESS_WRITE
|
1107 NTCREATEX_SHARE_ACCESS_DELETE
,
1108 NTCREATEX_DISP_CREATE
,
1110 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1111 fname
, smbcli_errstr(cli1
->tree
)));
1113 /* And close - just to create the file. */
1114 smbcli_close(cli1
->tree
, fnum1
);
1116 /* Next open with all access, but add delete on close. */
1117 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1118 SEC_RIGHTS_FILE_ALL
,
1119 FILE_ATTRIBUTE_NORMAL
,
1120 NTCREATEX_SHARE_ACCESS_READ
|
1121 NTCREATEX_SHARE_ACCESS_WRITE
|
1122 NTCREATEX_SHARE_ACCESS_DELETE
,
1123 NTCREATEX_DISP_OPEN
,
1124 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1126 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1127 fname
, smbcli_errstr(cli1
->tree
)));
1129 /* The delete on close bit is *not* reported as being set. */
1130 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1132 /* Now try opening again for read-only. */
1133 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1134 SEC_RIGHTS_FILE_READ
|
1136 FILE_ATTRIBUTE_NORMAL
,
1137 NTCREATEX_SHARE_ACCESS_READ
|
1138 NTCREATEX_SHARE_ACCESS_WRITE
|
1139 NTCREATEX_SHARE_ACCESS_DELETE
,
1140 NTCREATEX_DISP_OPEN
,
1144 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1145 fname
, smbcli_errstr(cli1
->tree
)));
1147 /* still not reported as being set on either */
1148 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1149 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1151 smbcli_close(cli1
->tree
, fnum2
);
1153 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1155 smbcli_close(cli1
->tree
, fnum1
);
1158 * The file is still there:
1159 * The second open seems to have removed the initial
1160 * delete on close flag from the first handle
1162 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1163 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1164 fname
, smbcli_errstr(cli1
->tree
)));
1166 smbcli_close(cli1
->tree
, fnum1
);
1167 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1168 smbcli_unlink(cli1
->tree
, fname
);
1173 /* Test 17b - like 17a, but the initial delete on close is set on the second handle */
1174 static bool deltest17b(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1178 bool correct
= true;
1180 del_clean_area(cli1
, cli2
);
1182 /* Ensure the file doesn't already exist. */
1183 smbcli_close(cli1
->tree
, fnum1
);
1184 smbcli_close(cli1
->tree
, fnum2
);
1185 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1186 smbcli_unlink(cli1
->tree
, fname
);
1188 /* Firstly open and create with all access */
1189 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1190 SEC_RIGHTS_FILE_ALL
,
1191 FILE_ATTRIBUTE_NORMAL
,
1192 NTCREATEX_SHARE_ACCESS_READ
|
1193 NTCREATEX_SHARE_ACCESS_WRITE
|
1194 NTCREATEX_SHARE_ACCESS_DELETE
,
1195 NTCREATEX_DISP_CREATE
,
1197 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1198 fname
, smbcli_errstr(cli1
->tree
)));
1200 /* And close - just to create the file. */
1201 smbcli_close(cli1
->tree
, fnum1
);
1203 /* Next open with all access, but add delete on close. */
1204 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1205 SEC_RIGHTS_FILE_ALL
,
1206 FILE_ATTRIBUTE_NORMAL
,
1207 NTCREATEX_SHARE_ACCESS_READ
|
1208 NTCREATEX_SHARE_ACCESS_WRITE
|
1209 NTCREATEX_SHARE_ACCESS_DELETE
,
1210 NTCREATEX_DISP_OPEN
,
1213 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1214 fname
, smbcli_errstr(cli1
->tree
)));
1216 /* The delete on close bit is *not* reported as being set. */
1217 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1219 /* Now try opening again for read-only. */
1220 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1221 SEC_RIGHTS_FILE_READ
|
1223 FILE_ATTRIBUTE_NORMAL
,
1224 NTCREATEX_SHARE_ACCESS_READ
|
1225 NTCREATEX_SHARE_ACCESS_WRITE
|
1226 NTCREATEX_SHARE_ACCESS_DELETE
,
1227 NTCREATEX_DISP_OPEN
,
1228 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1231 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1232 fname
, smbcli_errstr(cli1
->tree
)));
1234 /* still not reported as being set on either */
1235 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1236 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1238 smbcli_close(cli1
->tree
, fnum1
);
1240 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1242 smbcli_close(cli1
->tree
, fnum2
);
1244 /* Make sure the file has been deleted */
1245 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1246 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeeded (should fail)",
1249 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1254 /* Test 17c - like 17, but the initial delete on close is set on the second handle */
1255 static bool deltest17c(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1259 bool correct
= true;
1261 del_clean_area(cli1
, cli2
);
1263 /* Ensure the file doesn't already exist. */
1264 smbcli_close(cli1
->tree
, fnum1
);
1265 smbcli_close(cli1
->tree
, fnum2
);
1266 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1267 smbcli_unlink(cli1
->tree
, fname
);
1269 /* Firstly open and create with all access */
1270 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1271 SEC_RIGHTS_FILE_ALL
,
1272 FILE_ATTRIBUTE_NORMAL
,
1273 NTCREATEX_SHARE_ACCESS_READ
|
1274 NTCREATEX_SHARE_ACCESS_WRITE
|
1275 NTCREATEX_SHARE_ACCESS_DELETE
,
1276 NTCREATEX_DISP_CREATE
,
1278 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1279 fname
, smbcli_errstr(cli1
->tree
)));
1281 /* And close - just to create the file. */
1282 smbcli_close(cli1
->tree
, fnum1
);
1284 /* Next open with all access, but add delete on close. */
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_OPEN
,
1294 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1295 fname
, smbcli_errstr(cli1
->tree
)));
1297 /* The delete on close bit is *not* reported as being set. */
1298 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1300 /* Now try opening again for read-only. */
1301 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1302 SEC_RIGHTS_FILE_READ
|
1304 FILE_ATTRIBUTE_NORMAL
,
1305 NTCREATEX_SHARE_ACCESS_READ
|
1306 NTCREATEX_SHARE_ACCESS_WRITE
|
1307 NTCREATEX_SHARE_ACCESS_DELETE
,
1308 NTCREATEX_DISP_OPEN
,
1309 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1312 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1313 fname
, smbcli_errstr(cli1
->tree
)));
1315 /* still not reported as being set on either */
1316 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1317 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1319 smbcli_close(cli1
->tree
, fnum2
);
1321 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
1323 fnum2
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1324 torture_assert(tctx
, fnum2
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeeded (should fail)",
1327 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1329 smbcli_close(cli1
->tree
, fnum1
);
1331 /* Make sure the file has been deleted */
1332 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1333 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1336 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1341 /* Test 17d - like 17a, but the first delete-on-close opener creates the file */
1342 static bool deltest17d(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1346 bool correct
= true;
1348 del_clean_area(cli1
, cli2
);
1350 /* Ensure the file doesn't already exist. */
1351 smbcli_close(cli1
->tree
, fnum1
);
1352 smbcli_close(cli1
->tree
, fnum2
);
1353 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1354 smbcli_unlink(cli1
->tree
, fname
);
1357 /* Create the file with delete on close. */
1358 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1359 SEC_RIGHTS_FILE_ALL
,
1360 FILE_ATTRIBUTE_NORMAL
,
1361 NTCREATEX_SHARE_ACCESS_READ
|
1362 NTCREATEX_SHARE_ACCESS_WRITE
|
1363 NTCREATEX_SHARE_ACCESS_DELETE
,
1364 NTCREATEX_DISP_CREATE
,
1365 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1367 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1368 fname
, smbcli_errstr(cli1
->tree
)));
1370 /* The delete on close bit is *not* reported as being set. */
1371 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1373 /* Now try opening again for read-only. */
1374 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1375 SEC_RIGHTS_FILE_READ
|
1377 FILE_ATTRIBUTE_NORMAL
,
1378 NTCREATEX_SHARE_ACCESS_READ
|
1379 NTCREATEX_SHARE_ACCESS_WRITE
|
1380 NTCREATEX_SHARE_ACCESS_DELETE
,
1381 NTCREATEX_DISP_OPEN
,
1385 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1386 fname
, smbcli_errstr(cli1
->tree
)));
1388 /* still not reported as being set on either */
1389 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1390 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1392 smbcli_close(cli1
->tree
, fnum2
);
1394 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1396 smbcli_close(cli1
->tree
, fnum1
);
1399 * The file is still there:
1400 * The second open seems to have removed the initial
1401 * delete on close flag from the first handle
1403 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1404 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 3 of %s succeed (should fail)",
1407 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1412 static bool deltest17e(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1417 bool correct
= true;
1419 del_clean_area(cli1
, cli2
);
1421 /* Ensure the file doesn't already exist. */
1422 smbcli_close(cli1
->tree
, fnum1
);
1423 smbcli_close(cli1
->tree
, fnum2
);
1424 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1425 smbcli_unlink(cli1
->tree
, fname
);
1427 /* Firstly open and create with all access */
1428 fnum3
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1429 SEC_RIGHTS_FILE_ALL
,
1430 FILE_ATTRIBUTE_NORMAL
,
1431 NTCREATEX_SHARE_ACCESS_READ
|
1432 NTCREATEX_SHARE_ACCESS_WRITE
|
1433 NTCREATEX_SHARE_ACCESS_DELETE
,
1434 NTCREATEX_DISP_CREATE
,
1436 torture_assert(tctx
, fnum3
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1437 fname
, smbcli_errstr(cli1
->tree
)));
1439 /* Next open with all access, but add delete on close. */
1440 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1441 SEC_RIGHTS_FILE_ALL
,
1442 FILE_ATTRIBUTE_NORMAL
,
1443 NTCREATEX_SHARE_ACCESS_READ
|
1444 NTCREATEX_SHARE_ACCESS_WRITE
|
1445 NTCREATEX_SHARE_ACCESS_DELETE
,
1446 NTCREATEX_DISP_OPEN
,
1447 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1449 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1450 fname
, smbcli_errstr(cli1
->tree
)));
1452 /* The delete on close bit is *not* reported as being set. */
1453 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1454 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1456 /* Now try opening again for read-only. */
1457 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1458 SEC_RIGHTS_FILE_READ
|
1460 FILE_ATTRIBUTE_NORMAL
,
1461 NTCREATEX_SHARE_ACCESS_READ
|
1462 NTCREATEX_SHARE_ACCESS_WRITE
|
1463 NTCREATEX_SHARE_ACCESS_DELETE
,
1464 NTCREATEX_DISP_OPEN
,
1468 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1469 fname
, smbcli_errstr(cli1
->tree
)));
1471 /* still not reported as being set on either */
1472 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1473 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1474 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1476 smbcli_close(cli1
->tree
, fnum1
);
1479 * closing the handle that has delete_on_close set
1480 * inherits the flag to the global context
1482 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1483 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1485 smbcli_close(cli1
->tree
, fnum2
);
1487 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1489 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1490 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1493 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1495 smbcli_close(cli1
->tree
, fnum3
);
1497 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1498 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 5 of %s succeeded (should fail)",
1501 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1506 static bool deltest17f(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1511 bool correct
= true;
1514 del_clean_area(cli1
, cli2
);
1516 /* Ensure the file doesn't already exist. */
1517 smbcli_close(cli1
->tree
, fnum1
);
1518 smbcli_close(cli1
->tree
, fnum2
);
1519 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1520 smbcli_unlink(cli1
->tree
, fname
);
1522 /* Firstly open and create with all access */
1523 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1524 SEC_RIGHTS_FILE_ALL
,
1525 FILE_ATTRIBUTE_NORMAL
,
1526 NTCREATEX_SHARE_ACCESS_READ
|
1527 NTCREATEX_SHARE_ACCESS_WRITE
|
1528 NTCREATEX_SHARE_ACCESS_DELETE
,
1529 NTCREATEX_DISP_CREATE
,
1530 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1531 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1532 fname
, smbcli_errstr(cli1
->tree
)));
1534 /* The delete on close bit is *not* reported as being set. */
1535 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1537 /* Next open with all access, but add delete on close. */
1538 fnum2
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1539 SEC_RIGHTS_FILE_ALL
,
1540 FILE_ATTRIBUTE_NORMAL
,
1541 NTCREATEX_SHARE_ACCESS_READ
|
1542 NTCREATEX_SHARE_ACCESS_WRITE
|
1543 NTCREATEX_SHARE_ACCESS_DELETE
,
1544 NTCREATEX_DISP_OPEN
,
1545 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1547 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1548 fname
, smbcli_errstr(cli1
->tree
)));
1550 /* still not reported as being set on either */
1551 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1552 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1554 /* Now try opening again for read-only. */
1555 fnum3
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1556 SEC_RIGHTS_FILE_READ
|
1558 FILE_ATTRIBUTE_NORMAL
,
1559 NTCREATEX_SHARE_ACCESS_READ
|
1560 NTCREATEX_SHARE_ACCESS_WRITE
|
1561 NTCREATEX_SHARE_ACCESS_DELETE
,
1562 NTCREATEX_DISP_OPEN
,
1563 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1566 torture_assert(tctx
, fnum3
!= -1, talloc_asprintf(tctx
, "open - 3 of %s failed (%s)",
1567 fname
, smbcli_errstr(cli1
->tree
)));
1569 /* still not reported as being set on either */
1570 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1571 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1572 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1574 smbcli_close(cli1
->tree
, fnum1
);
1577 * closing the handle that has delete_on_close set
1578 * inherits the flag to the global context
1580 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, true, __location__
);
1581 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1584 status
= smbcli_nt_delete_on_close(cli1
->tree
, fnum2
, false);
1585 torture_assert_ntstatus_ok(tctx
, status
,
1586 "clearing delete_on_close on file failed !");
1588 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, fname
, false, __location__
);
1589 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, false, __location__
);
1591 smbcli_close(cli1
->tree
, fnum2
);
1593 correct
&= check_delete_on_close(tctx
, cli1
, fnum3
, fname
, true, __location__
);
1595 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1596 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 4 of %s succeeded (should fail)",
1599 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
1601 smbcli_close(cli1
->tree
, fnum3
);
1603 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1604 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open - 5 of %s succeeded (should fail)",
1607 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1613 static bool deltest18(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1617 bool correct
= true;
1619 del_clean_area(cli1
, cli2
);
1621 /* Test 18. With directories. */
1623 /* Ensure the file doesn't already exist. */
1624 smbcli_close(cli1
->tree
, fnum1
);
1625 smbcli_close(cli1
->tree
, fnum2
);
1627 smbcli_deltree(cli1
->tree
, dname
);
1629 /* Firstly create with all access, but delete on close. */
1630 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1632 SEC_FILE_WRITE_DATA
|
1634 FILE_ATTRIBUTE_DIRECTORY
,
1635 NTCREATEX_SHARE_ACCESS_READ
|
1636 NTCREATEX_SHARE_ACCESS_WRITE
|
1637 NTCREATEX_SHARE_ACCESS_DELETE
,
1638 NTCREATEX_DISP_CREATE
,
1639 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1641 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1642 dname
, smbcli_errstr(cli1
->tree
)));
1645 * The delete on close bit is *not* reported as being set.
1646 * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
1647 * close as being set. This causes the subsequent create to fail with
1648 * NT_STATUS_DELETE_PENDING.
1650 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1652 /* Now try opening again for read-only. */
1653 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1654 SEC_RIGHTS_FILE_READ
,
1655 FILE_ATTRIBUTE_DIRECTORY
,
1656 NTCREATEX_SHARE_ACCESS_READ
|
1657 NTCREATEX_SHARE_ACCESS_WRITE
|
1658 NTCREATEX_SHARE_ACCESS_DELETE
,
1659 NTCREATEX_DISP_OPEN
,
1660 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1664 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1665 dname
, smbcli_errstr(cli1
->tree
)));
1667 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1668 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, false, __location__
);
1670 smbcli_close(cli1
->tree
, fnum1
);
1672 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, true, __location__
);
1674 smbcli_close(cli1
->tree
, fnum2
);
1676 /* And the directory should be deleted ! */
1677 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1678 SEC_RIGHTS_FILE_READ
,
1679 FILE_ATTRIBUTE_DIRECTORY
,
1680 NTCREATEX_SHARE_ACCESS_READ
|
1681 NTCREATEX_SHARE_ACCESS_WRITE
|
1682 NTCREATEX_SHARE_ACCESS_DELETE
,
1683 NTCREATEX_DISP_OPEN
,
1684 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1685 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail)",
1692 static bool deltest19(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1696 bool correct
= true;
1698 del_clean_area(cli1
, cli2
);
1702 smbcli_deltree(cli1
->tree
, dname
);
1704 /* Firstly open and create with all access */
1705 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1707 SEC_FILE_WRITE_DATA
|
1709 FILE_ATTRIBUTE_DIRECTORY
,
1710 NTCREATEX_SHARE_ACCESS_READ
|
1711 NTCREATEX_SHARE_ACCESS_WRITE
|
1712 NTCREATEX_SHARE_ACCESS_DELETE
,
1713 NTCREATEX_DISP_CREATE
,
1714 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1716 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1717 dname
, smbcli_errstr(cli1
->tree
)));
1719 /* And close - just to create the directory. */
1720 smbcli_close(cli1
->tree
, fnum1
);
1722 /* Next open with all access, but add delete on close. */
1723 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1725 SEC_FILE_WRITE_DATA
|
1727 FILE_ATTRIBUTE_DIRECTORY
,
1728 NTCREATEX_SHARE_ACCESS_READ
|
1729 NTCREATEX_SHARE_ACCESS_WRITE
|
1730 NTCREATEX_SHARE_ACCESS_DELETE
,
1731 NTCREATEX_DISP_OPEN
,
1732 NTCREATEX_OPTIONS_DIRECTORY
|NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1734 torture_assert(tctx
, fnum1
!= -1,
1735 talloc_asprintf(tctx
, "open - 1 of %s failed (%s)", fname
, smbcli_errstr(cli1
->tree
)));
1738 * The delete on close bit is *not* reported as being set.
1739 * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
1740 * close as being set. This causes the subsequent create to fail with
1741 * NT_STATUS_DELETE_PENDING.
1743 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, dname
, false, __location__
);
1745 /* Now try opening again for read-only. */
1746 fnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1747 SEC_RIGHTS_FILE_READ
,
1748 FILE_ATTRIBUTE_DIRECTORY
,
1749 NTCREATEX_SHARE_ACCESS_READ
|
1750 NTCREATEX_SHARE_ACCESS_WRITE
|
1751 NTCREATEX_SHARE_ACCESS_DELETE
,
1752 NTCREATEX_DISP_OPEN
,
1753 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1756 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1757 dname
, smbcli_errstr(cli1
->tree
)));
1759 smbcli_close(cli1
->tree
, fnum1
);
1761 correct
&= check_delete_on_close(tctx
, cli1
, fnum2
, dname
, true, __location__
);
1763 smbcli_close(cli1
->tree
, fnum2
);
1765 /* See if the file is deleted - for a directory this seems to be true ! */
1766 fnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1767 SEC_RIGHTS_FILE_READ
,
1768 FILE_ATTRIBUTE_DIRECTORY
,
1769 NTCREATEX_SHARE_ACCESS_READ
|
1770 NTCREATEX_SHARE_ACCESS_WRITE
|
1771 NTCREATEX_SHARE_ACCESS_DELETE
,
1772 NTCREATEX_DISP_OPEN
,
1773 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1775 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
1777 torture_assert(tctx
, fnum1
== -1,
1778 talloc_asprintf(tctx
, "open of %s succeeded (should fail)", dname
));
1784 static bool deltest20(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1788 bool correct
= true;
1792 del_clean_area(cli1
, cli2
);
1794 /* Test 20 -- non-empty directory hardest to get right... */
1796 smbcli_deltree(cli1
->tree
, dname
);
1798 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
1800 SEC_FILE_WRITE_DATA
|
1802 FILE_ATTRIBUTE_DIRECTORY
,
1803 NTCREATEX_SHARE_ACCESS_READ
|
1804 NTCREATEX_SHARE_ACCESS_WRITE
|
1805 NTCREATEX_SHARE_ACCESS_DELETE
,
1806 NTCREATEX_DISP_CREATE
,
1807 NTCREATEX_OPTIONS_DIRECTORY
, 0);
1808 torture_assert(tctx
, dnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed: %s!",
1809 dname
, smbcli_errstr(cli1
->tree
)));
1811 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, false, __location__
);
1812 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
1816 ret
= asprintf(&fullname
, "\\%s%s", dname
, fname
);
1817 torture_assert(tctx
, ret
!= -1, "asprintf failed");
1818 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1820 torture_assert(tctx
, fnum1
== -1,
1821 "smbcli_open succeeded, should have "
1822 "failed with NT_STATUS_DELETE_PENDING"
1825 torture_assert_ntstatus_equal(tctx
,
1826 smbcli_nt_error(cli1
->tree
),
1827 NT_STATUS_DELETE_PENDING
,
1828 "smbcli_open failed");
1831 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, false);
1832 torture_assert_ntstatus_ok(tctx
, status
,
1833 "unsetting delete_on_close on file failed !");
1837 ret
= asprintf(&fullname
, "\\%s%s", dname
, fname
);
1838 torture_assert(tctx
, ret
!= -1, "asprintf failed");
1839 fnum1
= smbcli_open(cli1
->tree
, fullname
, O_CREAT
|O_RDWR
,
1841 torture_assert(tctx
, fnum1
!= -1,
1842 talloc_asprintf(tctx
, "smbcli_open failed: %s\n",
1843 smbcli_errstr(cli1
->tree
)));
1844 smbcli_close(cli1
->tree
, fnum1
);
1847 status
= smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
1849 torture_assert_ntstatus_equal(tctx
, status
, NT_STATUS_DIRECTORY_NOT_EMPTY
,
1850 "setting delete_on_close failed");
1851 smbcli_close(cli1
->tree
, dnum1
);
1857 static bool deltest20a(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1861 bool correct
= true;
1863 del_clean_area(cli1
, cli2
);
1867 /* Ensure the file doesn't already exist. */
1868 smbcli_close(cli1
->tree
, fnum1
);
1869 smbcli_close(cli1
->tree
, fnum2
);
1870 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1871 smbcli_unlink(cli1
->tree
, fname
);
1873 /* Firstly open and create with all access */
1874 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1875 SEC_RIGHTS_FILE_ALL
,
1876 FILE_ATTRIBUTE_NORMAL
,
1877 NTCREATEX_SHARE_ACCESS_READ
|
1878 NTCREATEX_SHARE_ACCESS_WRITE
|
1879 NTCREATEX_SHARE_ACCESS_DELETE
,
1880 NTCREATEX_DISP_CREATE
,
1882 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1883 fname
, smbcli_errstr(cli1
->tree
)));
1885 /* Next open with all access, but add delete on close. */
1886 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1887 SEC_RIGHTS_FILE_ALL
,
1888 FILE_ATTRIBUTE_NORMAL
,
1889 NTCREATEX_SHARE_ACCESS_READ
|
1890 NTCREATEX_SHARE_ACCESS_WRITE
|
1891 NTCREATEX_SHARE_ACCESS_DELETE
,
1892 NTCREATEX_DISP_OPEN
,
1893 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1895 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1896 fname
, smbcli_errstr(cli2
->tree
)));
1898 /* The delete on close bit is *not* reported as being set. */
1899 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1900 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1902 smbcli_close(cli1
->tree
, fnum1
);
1904 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1906 smbcli_close(cli2
->tree
, fnum2
);
1908 /* See if the file is deleted - should be.... */
1909 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
1910 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
1911 fname
, smbcli_errstr(cli1
->tree
)));
1917 /* This is the delete semantics that the cifsfs client depends on when
1918 * trying to delete an open file on a Windows server. It
1919 * opens a file with initial delete on close set, renames it then closes
1920 * all open handles. The file goes away on Windows.
1923 static bool deltest20b(struct torture_context
*tctx
, struct smbcli_state
*cli1
, struct smbcli_state
*cli2
)
1927 bool correct
= true;
1929 del_clean_area(cli1
, cli2
);
1933 /* Ensure the file doesn't already exist. */
1934 smbcli_close(cli1
->tree
, fnum1
);
1935 smbcli_close(cli1
->tree
, fnum2
);
1936 smbcli_setatr(cli1
->tree
, fname
, 0, 0);
1937 smbcli_unlink(cli1
->tree
, fname
);
1938 smbcli_setatr(cli1
->tree
, fname_new
, 0, 0);
1939 smbcli_unlink(cli1
->tree
, fname_new
);
1941 /* Firstly open and create with all access */
1942 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1943 SEC_RIGHTS_FILE_ALL
,
1944 FILE_ATTRIBUTE_NORMAL
,
1945 NTCREATEX_SHARE_ACCESS_READ
|
1946 NTCREATEX_SHARE_ACCESS_WRITE
|
1947 NTCREATEX_SHARE_ACCESS_DELETE
,
1948 NTCREATEX_DISP_CREATE
,
1950 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1951 fname
, smbcli_errstr(cli1
->tree
)));
1953 /* And close - just to create the file. */
1954 smbcli_close(cli1
->tree
, fnum1
);
1956 /* Firstly open and create with all access */
1957 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
1958 SEC_RIGHTS_FILE_ALL
,
1959 FILE_ATTRIBUTE_NORMAL
,
1960 NTCREATEX_SHARE_ACCESS_READ
|
1961 NTCREATEX_SHARE_ACCESS_WRITE
|
1962 NTCREATEX_SHARE_ACCESS_DELETE
,
1963 NTCREATEX_DISP_OPEN
,
1965 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open - 1 of %s failed (%s)",
1966 fname
, smbcli_errstr(cli1
->tree
)));
1968 /* Next open with all access, but add delete on close. */
1969 fnum2
= smbcli_nt_create_full(cli2
->tree
, fname
, 0,
1970 SEC_RIGHTS_FILE_ALL
,
1971 FILE_ATTRIBUTE_NORMAL
,
1972 NTCREATEX_SHARE_ACCESS_READ
|
1973 NTCREATEX_SHARE_ACCESS_WRITE
|
1974 NTCREATEX_SHARE_ACCESS_DELETE
,
1975 NTCREATEX_DISP_OPEN
,
1976 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
1978 torture_assert(tctx
, fnum2
!= -1, talloc_asprintf(tctx
, "open - 2 of %s failed (%s)",
1979 fname
, smbcli_errstr(cli2
->tree
)));
1981 /* The delete on close bit is *not* reported as being set. */
1982 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, false, __location__
);
1983 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1985 smbcli_close(cli1
->tree
, fnum1
);
1987 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname
, false, __location__
);
1989 /* Rename the file by handle. */
1992 union smb_setfileinfo sfinfo
;
1995 memset(&sfinfo
, '\0', sizeof(sfinfo
));
1996 sfinfo
.generic
.level
= RAW_SFILEINFO_RENAME_INFORMATION
;
1997 sfinfo
.generic
.in
.file
.fnum
= fnum2
;
1998 sfinfo
.rename_information
.in
.root_fid
= 0;
1999 /* Don't start the filename with '\\', we get NT_STATUS_NOT_SUPPORTED if so. */
2000 sfinfo
.rename_information
.in
.new_name
= fname_new
+ 1;
2001 sfinfo
.rename_information
.in
.overwrite
= 1;
2003 status
= smb_raw_setfileinfo(cli2
->tree
, &sfinfo
);
2005 torture_assert_ntstatus_equal(tctx
,status
,NT_STATUS_OK
,talloc_asprintf(tctx
, "rename of %s to %s failed (%s)",
2006 fname
, fname_new
, smbcli_errstr(cli2
->tree
)));
2009 correct
&= check_delete_on_close(tctx
, cli2
, fnum2
, fname_new
, false, __location__
);
2011 smbcli_close(cli2
->tree
, fnum2
);
2013 /* See if the file is deleted - should be.... */
2014 fnum1
= smbcli_open(cli1
->tree
, fname
, O_RDWR
, DENY_NONE
);
2015 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
2016 fname
, smbcli_errstr(cli1
->tree
)));
2017 fnum1
= smbcli_open(cli1
->tree
, fname_new
, O_RDWR
, DENY_NONE
);
2018 torture_assert(tctx
, fnum1
== -1, talloc_asprintf(tctx
, "open of %s succeeded (should fail) - %s",
2019 fname_new
, smbcli_errstr(cli1
->tree
)));
2026 static bool deltest21(struct torture_context
*tctx
)
2029 struct smbcli_state
*cli1
;
2030 struct smbcli_state
*cli2
;
2031 bool correct
= true;
2033 if (!torture_open_connection(&cli1
, tctx
, 0))
2036 if (!torture_open_connection(&cli2
, tctx
, 1))
2039 del_clean_area(cli1
, cli2
);
2041 /* Test 21 -- Test removal of file after socket close. */
2043 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2044 SEC_RIGHTS_FILE_ALL
,
2045 FILE_ATTRIBUTE_NORMAL
, NTCREATEX_SHARE_ACCESS_NONE
,
2046 NTCREATEX_DISP_OVERWRITE_IF
, 0, 0);
2048 torture_assert(tctx
, fnum1
!= -1, talloc_asprintf(tctx
, "open of %s failed (%s)",
2049 fname
, smbcli_errstr(cli1
->tree
)));
2051 torture_assert_ntstatus_ok(tctx
,
2052 smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, true),
2053 talloc_asprintf(tctx
, "setting delete_on_close failed (%s)",
2054 smbcli_errstr(cli1
->tree
)));
2056 /* Ensure delete on close is set. */
2057 correct
&= check_delete_on_close(tctx
, cli1
, fnum1
, fname
, true, __location__
);
2059 /* Now yank the rug from under cli1. */
2060 smbcli_transport_dead(cli1
->transport
, NT_STATUS_LOCAL_DISCONNECT
);
2064 if (!torture_open_connection(&cli1
, tctx
, 0)) {
2068 /* On slow build farm machines it might happen that they are not fast
2069 * enogh to delete the file for this test */
2072 /* File should not be there. */
2073 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2074 SEC_RIGHTS_FILE_READ
,
2075 FILE_ATTRIBUTE_NORMAL
,
2076 NTCREATEX_SHARE_ACCESS_READ
|
2077 NTCREATEX_SHARE_ACCESS_WRITE
|
2078 NTCREATEX_SHARE_ACCESS_DELETE
,
2079 NTCREATEX_DISP_OPEN
,
2082 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2090 * Test whether a second *directory* handle inhibits delete if the first has
2091 * del-on-close set and is closed
2093 static bool deltest22(struct torture_context
*tctx
)
2097 struct smbcli_state
*cli1
;
2098 bool correct
= true;
2100 if (!torture_open_connection(&cli1
, tctx
, 0))
2103 smbcli_deltree(cli1
->tree
, dname
);
2105 torture_assert_ntstatus_ok(
2106 tctx
, smbcli_mkdir(cli1
->tree
, dname
),
2107 talloc_asprintf(tctx
, "smbcli_mdir failed: (%s)\n",
2108 smbcli_errstr(cli1
->tree
)));
2110 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2112 SEC_FILE_WRITE_DATA
|
2114 FILE_ATTRIBUTE_DIRECTORY
,
2115 NTCREATEX_SHARE_ACCESS_READ
|
2116 NTCREATEX_SHARE_ACCESS_WRITE
|
2117 NTCREATEX_SHARE_ACCESS_DELETE
,
2118 NTCREATEX_DISP_OPEN
,
2119 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2121 torture_assert(tctx
, dnum1
!= -1,
2122 talloc_asprintf(tctx
, "open of %s failed: %s!",
2123 dname
, smbcli_errstr(cli1
->tree
)));
2125 dnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2127 SEC_FILE_WRITE_DATA
,
2128 FILE_ATTRIBUTE_DIRECTORY
,
2129 NTCREATEX_SHARE_ACCESS_READ
|
2130 NTCREATEX_SHARE_ACCESS_WRITE
|
2131 NTCREATEX_SHARE_ACCESS_DELETE
,
2132 NTCREATEX_DISP_OPEN
,
2133 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2135 torture_assert(tctx
, dnum2
!= -1,
2136 talloc_asprintf(tctx
, "open of %s failed: %s!",
2137 dname
, smbcli_errstr(cli1
->tree
)));
2139 torture_assert_ntstatus_ok(
2140 tctx
, smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true),
2141 talloc_asprintf(tctx
, "setting delete_on_close failed (%s)",
2142 smbcli_errstr(cli1
->tree
)));
2144 smbcli_close(cli1
->tree
, dnum1
);
2146 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2148 SEC_FILE_WRITE_DATA
|
2150 FILE_ATTRIBUTE_DIRECTORY
,
2151 NTCREATEX_SHARE_ACCESS_READ
|
2152 NTCREATEX_SHARE_ACCESS_WRITE
|
2153 NTCREATEX_SHARE_ACCESS_DELETE
,
2154 NTCREATEX_DISP_OPEN
,
2155 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2157 torture_assert(tctx
, dnum1
== -1,
2158 talloc_asprintf(tctx
, "open of %s succeeded!\n",
2161 CHECK_STATUS(cli1
, NT_STATUS_DELETE_PENDING
);
2163 smbcli_close(cli1
->tree
, dnum2
);
2164 CHECK_STATUS(cli1
, NT_STATUS_OK
);
2169 /* Test 23 - Second directory open fails when delete is pending. */
2170 static bool deltest23(struct torture_context
*tctx
,
2171 struct smbcli_state
*cli1
,
2172 struct smbcli_state
*cli2
)
2176 bool correct
= true;
2178 del_clean_area(cli1
, cli2
);
2180 /* Test 23 -- Basic delete on close for directories. */
2182 /* Open a directory */
2183 dnum1
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2185 SEC_FILE_WRITE_DATA
|
2187 FILE_ATTRIBUTE_DIRECTORY
,
2188 NTCREATEX_SHARE_ACCESS_READ
|
2189 NTCREATEX_SHARE_ACCESS_WRITE
|
2190 NTCREATEX_SHARE_ACCESS_DELETE
,
2191 NTCREATEX_DISP_CREATE
,
2192 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2194 torture_assert(tctx
, dnum1
!= -1, talloc_asprintf(tctx
,
2195 "open of %s failed: %s!",
2196 dname
, smbcli_errstr(cli1
->tree
)));
2198 correct
&= check_delete_on_close(tctx
, cli1
, dnum1
, dname
, false,
2201 /* Set delete on close */
2202 (void)smbcli_nt_delete_on_close(cli1
->tree
, dnum1
, true);
2204 /* Attempt opening the directory again. It should fail. */
2205 dnum2
= smbcli_nt_create_full(cli1
->tree
, dname
, 0,
2207 SEC_FILE_WRITE_DATA
|
2209 FILE_ATTRIBUTE_DIRECTORY
,
2210 NTCREATEX_SHARE_ACCESS_READ
|
2211 NTCREATEX_SHARE_ACCESS_WRITE
|
2212 NTCREATEX_SHARE_ACCESS_DELETE
,
2213 NTCREATEX_DISP_OPEN
,
2214 NTCREATEX_OPTIONS_DIRECTORY
, 0);
2216 torture_assert(tctx
, dnum2
== -1, talloc_asprintf(tctx
,
2217 "open of %s succeeded: %s. It should have failed "
2218 "with NT_STATUS_DELETE_PENDING",
2219 dname
, smbcli_errstr(cli1
->tree
)));
2221 torture_assert_ntstatus_equal(tctx
, smbcli_nt_error(cli1
->tree
),
2222 NT_STATUS_DELETE_PENDING
, "smbcli_open failed");
2230 * Test whether unsetting delete-on-close before the close has any effect.
2231 * It should be ignored.
2233 static bool deltest24(struct torture_context
*tctx
)
2236 struct smbcli_state
*cli1
;
2237 bool correct
= true;
2239 if (!torture_open_connection(&cli1
, tctx
, 0))
2242 smbcli_deltree(cli1
->tree
, fname
);
2244 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2246 SEC_FILE_WRITE_DATA
|
2248 FILE_ATTRIBUTE_NORMAL
,
2249 NTCREATEX_SHARE_ACCESS_READ
|
2250 NTCREATEX_SHARE_ACCESS_WRITE
|
2251 NTCREATEX_SHARE_ACCESS_DELETE
,
2252 NTCREATEX_DISP_CREATE
,
2253 NTCREATEX_OPTIONS_DELETE_ON_CLOSE
, 0);
2255 torture_assert(tctx
, fnum1
!= -1,
2256 talloc_asprintf(tctx
, "open of %s failed: %s!",
2257 fname
, smbcli_errstr(cli1
->tree
)));
2259 /* Now, unset Delete-On-Close, but it should have no effect */
2260 torture_assert_ntstatus_ok(
2261 tctx
, smbcli_nt_delete_on_close(cli1
->tree
, fnum1
, false),
2262 talloc_asprintf(tctx
, "unsetting delete_on_close failed (%s)",
2263 smbcli_errstr(cli1
->tree
)));
2265 smbcli_close(cli1
->tree
, fnum1
);
2267 /* File should not be there. */
2268 fnum1
= smbcli_nt_create_full(cli1
->tree
, fname
, 0,
2269 SEC_RIGHTS_FILE_READ
,
2270 FILE_ATTRIBUTE_NORMAL
,
2271 NTCREATEX_SHARE_ACCESS_READ
|
2272 NTCREATEX_SHARE_ACCESS_WRITE
|
2273 NTCREATEX_SHARE_ACCESS_DELETE
,
2274 NTCREATEX_DISP_OPEN
,
2277 CHECK_STATUS(cli1
, NT_STATUS_OBJECT_NAME_NOT_FOUND
);
2283 Test delete on close semantics.
2285 struct torture_suite
*torture_test_delete(TALLOC_CTX
*ctx
)
2287 struct torture_suite
*suite
= torture_suite_create(
2290 torture_suite_add_2smb_test(suite
, "deltest1", deltest1
);
2291 torture_suite_add_2smb_test(suite
, "deltest2", deltest2
);
2292 torture_suite_add_2smb_test(suite
, "deltest3", deltest3
);
2293 torture_suite_add_2smb_test(suite
, "deltest4", deltest4
);
2294 torture_suite_add_2smb_test(suite
, "deltest5", deltest5
);
2295 torture_suite_add_2smb_test(suite
, "deltest6", deltest6
);
2296 torture_suite_add_2smb_test(suite
, "deltest7", deltest7
);
2297 torture_suite_add_2smb_test(suite
, "deltest8", deltest8
);
2298 torture_suite_add_2smb_test(suite
, "deltest9", deltest9
);
2299 torture_suite_add_2smb_test(suite
, "deltest10", deltest10
);
2300 torture_suite_add_2smb_test(suite
, "deltest11", deltest11
);
2301 torture_suite_add_2smb_test(suite
, "deltest12", deltest12
);
2302 torture_suite_add_2smb_test(suite
, "deltest13", deltest13
);
2303 torture_suite_add_2smb_test(suite
, "deltest14", deltest14
);
2304 torture_suite_add_2smb_test(suite
, "deltest15", deltest15
);
2305 torture_suite_add_2smb_test(suite
, "deltest16", deltest16
);
2306 torture_suite_add_2smb_test(suite
, "deltest16a", deltest16a
);
2307 torture_suite_add_2smb_test(suite
, "deltest17", deltest17
);
2308 torture_suite_add_2smb_test(suite
, "deltest17a", deltest17a
);
2309 torture_suite_add_2smb_test(suite
, "deltest17b", deltest17b
);
2310 torture_suite_add_2smb_test(suite
, "deltest17c", deltest17c
);
2311 torture_suite_add_2smb_test(suite
, "deltest17d", deltest17d
);
2312 torture_suite_add_2smb_test(suite
, "deltest17e", deltest17e
);
2313 torture_suite_add_2smb_test(suite
, "deltest17f", deltest17f
);
2314 torture_suite_add_2smb_test(suite
, "deltest18", deltest18
);
2315 torture_suite_add_2smb_test(suite
, "deltest19", deltest19
);
2316 torture_suite_add_2smb_test(suite
, "deltest20", deltest20
);
2317 torture_suite_add_2smb_test(suite
, "deltest20a", deltest20a
);
2318 torture_suite_add_2smb_test(suite
, "deltest20b", deltest20b
);
2319 torture_suite_add_simple_test(suite
, "deltest21", deltest21
);
2320 torture_suite_add_simple_test(suite
, "deltest22", deltest22
);
2321 torture_suite_add_2smb_test(suite
, "deltest23", deltest23
);
2322 torture_suite_add_simple_test(suite
, "deltest24", deltest24
);