LCOV - code coverage report
Current view: top level - source4/torture/basic - delete.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 821 837 98.1 %
Date: 2024-04-21 15:09:00 Functions: 40 40 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    delete on close testing
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/libcli.h"
      24             : #include "torture/util.h"
      25             : #include "system/filesys.h"
      26             : #include "libcli/raw/raw_proto.h"
      27             : 
      28             : #include "torture/raw/proto.h"
      29             : #include "torture/basic/proto.h"
      30             : 
      31         609 : static bool check_delete_on_close(struct torture_context *tctx,
      32             :                                   struct smbcli_state *cli, int fnum,
      33             :                                   const char *fname, bool expect_it,
      34             :                                   const char *where)
      35             : {
      36          87 :         union smb_search_data data;
      37          87 :         NTSTATUS status;
      38             : 
      39          87 :         time_t c_time, a_time, m_time;
      40          87 :         size_t size;
      41          87 :         uint16_t mode;
      42             : 
      43         609 :         status = torture_single_search(cli, tctx,
      44             :                                        fname,
      45             :                                        RAW_SEARCH_TRANS2,
      46             :                                        RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
      47             :                                        FILE_ATTRIBUTE_DIRECTORY,
      48             :                                        &data);
      49         609 :         torture_assert_ntstatus_ok(tctx, status,
      50             :                 talloc_asprintf(tctx, "single_search failed (%s)", where));
      51             : 
      52         609 :         if (fnum != -1) {
      53          76 :                 union smb_fileinfo io;
      54         532 :                 int nlink = expect_it ? 0 : 1;
      55             : 
      56         532 :                 io.all_info.level = RAW_FILEINFO_ALL_INFO;
      57         532 :                 io.all_info.in.file.fnum = fnum;
      58             : 
      59         532 :                 status = smb_raw_fileinfo(cli->tree, tctx, &io);
      60         532 :                 torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx,
      61             :                                         "qfileinfo failed (%s)", where));
      62             : 
      63         532 :                 torture_assert(tctx, expect_it == io.all_info.out.delete_pending,
      64             :                         talloc_asprintf(tctx,
      65             :                         "%s - Expected del_on_close flag %d, qfileinfo/all_info gave %d",
      66             :                                where, expect_it, io.all_info.out.delete_pending));
      67             : 
      68         515 :                 torture_assert(tctx, nlink == io.all_info.out.nlink,
      69             :                         talloc_asprintf(tctx,
      70             :                                 "%s - Expected nlink %d, qfileinfo/all_info gave %d",
      71             :                                where, nlink, io.all_info.out.nlink));
      72             : 
      73         515 :                 io.standard_info.level = RAW_FILEINFO_STANDARD_INFO;
      74         515 :                 io.standard_info.in.file.fnum = fnum;
      75             : 
      76         515 :                 status = smb_raw_fileinfo(cli->tree, tctx, &io);
      77         515 :                 torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "qpathinfo failed (%s)", where));
      78             : 
      79         515 :                 torture_assert(tctx, expect_it == io.standard_info.out.delete_pending,
      80             :                         talloc_asprintf(tctx, "%s - Expected del_on_close flag %d, qfileinfo/standard_info gave %d\n",
      81             :                                where, expect_it, io.standard_info.out.delete_pending));
      82             : 
      83         515 :                 torture_assert(tctx, nlink == io.standard_info.out.nlink,
      84             :                         talloc_asprintf(tctx, "%s - Expected nlink %d, qfileinfo/standard_info gave %d",
      85             :                                where, nlink, io.all_info.out.nlink));
      86             :         }
      87             : 
      88         592 :         status = smbcli_qpathinfo(cli->tree, fname,
      89             :                                   &c_time, &a_time, &m_time,
      90             :                                   &size, &mode);
      91             : 
      92         592 :         if (expect_it) {
      93         142 :                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_DELETE_PENDING,
      94             :                         "qpathinfo did not give correct error code");
      95             :         } else {
      96         450 :                 torture_assert_ntstatus_ok(tctx, status,
      97             :                         talloc_asprintf(tctx, "qpathinfo failed (%s)", where));
      98             :         }
      99             : 
     100         502 :         return true;
     101             : }
     102             : 
     103             : #define CHECK_STATUS(_cli, _expected) \
     104             :         torture_assert_ntstatus_equal(tctx, _cli->tree->session->transport->error.e.nt_status, _expected, \
     105             :                  "Incorrect status")
     106             : 
     107             : static const char *fname = "\\delete.file";
     108             : static const char *fname_new = "\\delete.new";
     109             : static const char *dname = "\\delete.dir";
     110             : 
     111         259 : static void del_clean_area(struct smbcli_state *cli1, struct smbcli_state *cli2)
     112             : {
     113         259 :         smb_raw_exit(cli1->session);
     114         259 :         smb_raw_exit(cli2->session);
     115             : 
     116         259 :         smbcli_deltree(cli1->tree, dname);
     117         259 :         smbcli_setatr(cli1->tree, fname, 0, 0);
     118         259 :         smbcli_unlink(cli1->tree, fname);
     119         259 :         smbcli_setatr(cli1->tree, fname_new, 0, 0);
     120         259 :         smbcli_unlink(cli1->tree, fname_new);
     121         259 : }
     122             : 
     123             : /* Test 1 - this should delete the file on close. */
     124             : 
     125           7 : static bool deltest1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     126             : {
     127           7 :         int fnum1 = -1;
     128             : 
     129           7 :         del_clean_area(cli1, cli2);
     130             : 
     131           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     132             :                                       SEC_RIGHTS_FILE_ALL,
     133             :                                       FILE_ATTRIBUTE_NORMAL,
     134             :                                       NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
     135             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     136             : 
     137           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     138             :                        fname, smbcli_errstr(cli1->tree)));
     139             : 
     140           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     141             :                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli1->tree)));
     142             : 
     143           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     144           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail)",
     145             :                        fname));
     146             : 
     147           6 :         return true;
     148             : }
     149             : 
     150             : /* Test 2 - this should delete the file on close. */
     151           7 : static bool deltest2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     152             : {
     153           7 :         int fnum1 = -1;
     154             : 
     155           7 :         del_clean_area(cli1, cli2);
     156             : 
     157           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     158             :                                       SEC_RIGHTS_FILE_ALL,
     159             :                                       FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
     160             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     161             : 
     162           7 :         torture_assert(tctx, fnum1 != -1,
     163             :                 talloc_asprintf(tctx, "open of %s failed (%s)",
     164             :                        fname, smbcli_errstr(cli1->tree)));
     165             : 
     166           7 :         torture_assert_ntstatus_ok(tctx, smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
     167             :                 talloc_asprintf(tctx, "setting delete_on_close failed (%s)",
     168             :                        smbcli_errstr(cli1->tree)));
     169             : 
     170           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     171             :                 talloc_asprintf(tctx, "close failed (%s)",
     172             :                        smbcli_errstr(cli1->tree)));
     173             : 
     174           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     175           7 :         if (fnum1 != -1) {
     176           0 :                 printf("(%s) open of %s succeeded should have been deleted on close !\n",
     177             :                        __location__, fname);
     178           0 :                 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     179           0 :                         printf("(%s) close failed (%s)\n",
     180             :                                __location__, smbcli_errstr(cli1->tree));
     181           0 :                         return false;
     182             :                 }
     183           0 :                 smbcli_unlink(cli1->tree, fname);
     184             :         }
     185           6 :         return true;
     186             : }
     187             : 
     188             : /* Test 3 - ... */
     189           7 : static bool deltest3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     190             : {
     191           7 :         int fnum1 = -1;
     192           7 :         int fnum2 = -1;
     193             : 
     194           7 :         del_clean_area(cli1, cli2);
     195             : 
     196           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     197             :                                       SEC_RIGHTS_FILE_ALL,
     198             :                                       FILE_ATTRIBUTE_NORMAL,
     199             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
     200             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     201             : 
     202           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
     203             :                         fname, smbcli_errstr(cli1->tree)));
     204             : 
     205             :         /* This should fail with a sharing violation - open for delete is only compatible
     206             :            with SHARE_DELETE. */
     207             : 
     208           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
     209             :                                       SEC_RIGHTS_FILE_READ,
     210             :                                       FILE_ATTRIBUTE_NORMAL,
     211             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
     212             :                                       NTCREATEX_DISP_OPEN, 0, 0);
     213             : 
     214           7 :         torture_assert(tctx, fnum2 == -1,
     215             :                 talloc_asprintf(tctx, "open  - 2 of %s succeeded - should have failed.",
     216             :                        fname));
     217             : 
     218             :         /* This should succeed. */
     219             : 
     220           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
     221             :                                       SEC_RIGHTS_FILE_READ,
     222             :                                       FILE_ATTRIBUTE_NORMAL,
     223             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
     224             :                                       NTCREATEX_DISP_OPEN, 0, 0);
     225             : 
     226           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open  - 2 of %s failed (%s)",
     227             :                        fname, smbcli_errstr(cli1->tree)));
     228             : 
     229           7 :         torture_assert_ntstatus_ok(tctx,
     230             :                                                            smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
     231             :                                                            talloc_asprintf(tctx, "setting delete_on_close failed (%s)",
     232             :                                                    smbcli_errstr(cli1->tree)));
     233             : 
     234           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     235             :                 talloc_asprintf(tctx, "close 1 failed (%s)",
     236             :                        smbcli_errstr(cli1->tree)));
     237             : 
     238           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum2),
     239             :                 talloc_asprintf(tctx, "close 2 failed (%s)",
     240             :                        smbcli_errstr(cli1->tree)));
     241             : 
     242             :         /* This should fail - file should no longer be there. */
     243             : 
     244           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     245           7 :         if (fnum1 != -1) {
     246           0 :                 printf("(%s) open of %s succeeded should have been deleted on close !\n",
     247             :                        __location__, fname);
     248           0 :                 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     249           0 :                         printf("(%s) close failed (%s)\n",
     250             :                                __location__, smbcli_errstr(cli1->tree));
     251             :                 }
     252           0 :                 smbcli_unlink(cli1->tree, fname);
     253           0 :                 return false;
     254             :         }
     255           6 :         return true;
     256             : }
     257             : 
     258             : /* Test 4 ... */
     259           7 : static bool deltest4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     260             : {
     261           7 :         int fnum1 = -1;
     262           7 :         int fnum2 = -1;
     263           7 :         bool correct = true;
     264             : 
     265           7 :         del_clean_area(cli1, cli2);
     266             : 
     267           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     268             :                                       SEC_FILE_READ_DATA  |
     269             :                                       SEC_FILE_WRITE_DATA |
     270             :                                       SEC_STD_DELETE,
     271             :                                       FILE_ATTRIBUTE_NORMAL,
     272             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
     273             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     274             : 
     275           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     276             :                        fname, smbcli_errstr(cli1->tree)));
     277             : 
     278             :         /* This should succeed. */
     279           7 :         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           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open  - 2 of %s failed (%s)",
     287             :                        fname, smbcli_errstr(cli1->tree)));
     288             : 
     289           7 :         torture_assert_ntstatus_ok(tctx,
     290             :                                         smbcli_close(cli1->tree, fnum2),
     291             :                                         talloc_asprintf(tctx, "close - 1 failed (%s)",
     292             :                                         smbcli_errstr(cli1->tree)));
     293             : 
     294           7 :         torture_assert_ntstatus_ok(tctx,
     295             :                                 smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
     296             :                                 talloc_asprintf(tctx, "setting delete_on_close failed (%s)",
     297             :                         smbcli_errstr(cli1->tree)));
     298             : 
     299             :         /* This should fail - no more opens once delete on close set. */
     300           7 :         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           7 :         torture_assert(tctx, fnum2 == -1,
     306             :                  talloc_asprintf(tctx, "open  - 3 of %s succeeded ! Should have failed.",
     307             :                        fname ));
     308             : 
     309           7 :         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
     310             : 
     311           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     312             :                  talloc_asprintf(tctx, "close - 2 failed (%s)",
     313             :                        smbcli_errstr(cli1->tree)));
     314             : 
     315           7 :         return correct;
     316             : }
     317             : 
     318             : /* Test 5 ... */
     319           7 : static bool deltest5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     320             : {
     321           7 :         int fnum1 = -1;
     322             : 
     323           7 :         del_clean_area(cli1, cli2);
     324             : 
     325           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
     326           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     327             :                        fname, smbcli_errstr(cli1->tree)));
     328             : 
     329             :         /* This should fail - only allowed on NT opens with DELETE access. */
     330             : 
     331           7 :         torture_assert(tctx, !NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, true)),
     332             :                  "setting delete_on_close on OpenX file succeeded - should fail !");
     333             : 
     334           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     335             :                 talloc_asprintf(tctx, "close - 2 failed (%s)", smbcli_errstr(cli1->tree)));
     336             : 
     337           7 :         return true;
     338             : }
     339             : 
     340             : /* Test 6 ... */
     341           7 : static bool deltest6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     342             : {
     343           7 :         int fnum1 = -1;
     344             : 
     345           7 :         del_clean_area(cli1, cli2);
     346             : 
     347           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     348             :                                    SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
     349             :                                    FILE_ATTRIBUTE_NORMAL,
     350             :                                    NTCREATEX_SHARE_ACCESS_READ  |
     351             :                                    NTCREATEX_SHARE_ACCESS_WRITE |
     352             :                                    NTCREATEX_SHARE_ACCESS_DELETE,
     353             :                                    NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     354             : 
     355           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     356             :                        fname, smbcli_errstr(cli1->tree)));
     357             : 
     358             :         /* This should fail - only allowed on NT opens with DELETE access. */
     359             : 
     360           7 :         torture_assert(tctx,
     361             :                 !NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, true)),
     362             :                 "setting delete_on_close on file with no delete access succeeded - should fail !");
     363             : 
     364           7 :         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)));
     369             : 
     370           7 :         return true;
     371             : }
     372             : 
     373             : /* Test 7 ... */
     374           7 : static bool deltest7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     375             : {
     376           7 :         int fnum1 = -1;
     377           7 :         bool correct = true;
     378             : 
     379           7 :         del_clean_area(cli1, cli2);
     380             : 
     381           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     382             :                                       SEC_FILE_READ_DATA  |
     383             :                                       SEC_FILE_WRITE_DATA |
     384             :                                       SEC_STD_DELETE,
     385             :                                       FILE_ATTRIBUTE_NORMAL, 0,
     386             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     387             : 
     388           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     389             :                        fname, smbcli_errstr(cli1->tree)));
     390             : 
     391           7 :         torture_assert_ntstatus_ok(tctx, smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
     392             :                         "setting delete_on_close on file failed !");
     393             : 
     394           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, true, __location__);
     395             : 
     396           7 :         torture_assert_ntstatus_ok(tctx,
     397             :                                         smbcli_nt_delete_on_close(cli1->tree, fnum1, false),
     398             :                                         "unsetting delete_on_close on file failed !");
     399             : 
     400           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
     401             : 
     402           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     403             :                 talloc_asprintf(tctx, "close - 2 failed (%s)", smbcli_errstr(cli1->tree)));
     404             : 
     405             :         /* This next open should succeed - we reset the flag. */
     406             : 
     407           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     408           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     409             :                        fname, smbcli_errstr(cli1->tree)));
     410             : 
     411           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     412             :                                                        talloc_asprintf(tctx, "close - 2 failed (%s)",
     413             :                                                    smbcli_errstr(cli1->tree)));
     414             : 
     415           7 :         return correct;
     416             : }
     417             : 
     418             : /* Test 8 ... */
     419           7 : static bool deltest8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     420             : {
     421           7 :         int fnum1 = -1;
     422           7 :         int fnum2 = -1;
     423           7 :         bool correct = true;
     424             : 
     425           7 :         del_clean_area(cli1, cli2);
     426             : 
     427           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     428             :                                       SEC_FILE_READ_DATA|
     429             :                                       SEC_FILE_WRITE_DATA|
     430             :                                       SEC_STD_DELETE,
     431             :                                       FILE_ATTRIBUTE_NORMAL,
     432             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
     433             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     434             : 
     435           7 :         torture_assert(tctx, fnum1 != -1,
     436             :                 talloc_asprintf(tctx, "open of %s failed (%s)",
     437             :                        fname, smbcli_errstr(cli1->tree)));
     438             : 
     439           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
     440             :                                       SEC_FILE_READ_DATA|
     441             :                                       SEC_FILE_WRITE_DATA|
     442             :                                       SEC_STD_DELETE,
     443             :                                       FILE_ATTRIBUTE_NORMAL,
     444             :                                       NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
     445             :                                       NTCREATEX_DISP_OPEN, 0, 0);
     446             : 
     447           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     448             :                        fname, smbcli_errstr(cli1->tree)));
     449             : 
     450           7 :         torture_assert_ntstatus_ok(tctx,
     451             :                                         smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
     452             :                 "setting delete_on_close on file failed !");
     453             : 
     454           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, true, __location__);
     455           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, true, __location__);
     456             : 
     457           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     458             :                 talloc_asprintf(tctx, "close - 1 failed (%s)",
     459             :                        smbcli_errstr(cli1->tree)));
     460             : 
     461           7 :         correct &= check_delete_on_close(tctx, cli1, -1, fname, true, __location__);
     462           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, true, __location__);
     463             : 
     464           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
     465             :                 talloc_asprintf(tctx, "close - 2 failed (%s)", smbcli_errstr(cli2->tree)));
     466             : 
     467             :         /* This should fail.. */
     468           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     469           7 :         torture_assert(tctx, fnum1 == -1,
     470             :                 talloc_asprintf(tctx, "open of %s succeeded should have been deleted on close !\n", fname));
     471             : 
     472           6 :         return correct;
     473             : }
     474             : 
     475             : /* Test 9 ... */
     476           7 : static bool deltest9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     477             : {
     478           7 :         int fnum1 = -1;
     479           1 :         NTSTATUS status;
     480           7 :         uint32_t disps[4] = {
     481             :                         NTCREATEX_DISP_SUPERSEDE,
     482             :                         NTCREATEX_DISP_OVERWRITE_IF,
     483             :                         NTCREATEX_DISP_CREATE,
     484             :                         NTCREATEX_DISP_OPEN_IF};
     485           1 :         unsigned int i;
     486             : 
     487           7 :         del_clean_area(cli1, cli2);
     488             : 
     489          36 :         for (i = 0; i < sizeof(disps)/sizeof(disps[0]); i++) {
     490             :                 /* This should fail - we need to set DELETE_ACCESS. */
     491             : 
     492             :                 /*
     493             :                  * A file or directory create with DELETE_ON_CLOSE but
     494             :                  * without DELETE_ACCESS should fail with
     495             :                  * NT_STATUS_INVALID_PARAMETER.
     496             :                  */
     497             : 
     498          28 :                 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     499             :                                 SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
     500             :                                 FILE_ATTRIBUTE_NORMAL,
     501             :                                 NTCREATEX_SHARE_ACCESS_NONE,
     502             :                                 disps[i],
     503             :                                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     504             : 
     505          28 :                 torture_assert(tctx, fnum1 == -1,
     506             :                         talloc_asprintf(tctx, "open of %s succeeded "
     507             :                                 "should have failed!",
     508             :                         fname));
     509             : 
     510             :                 /* Must fail with NT_STATUS_INVALID_PARAMETER. */
     511          28 :                 status = smbcli_nt_error(cli1->tree);
     512          28 :                 torture_assert_ntstatus_equal(tctx,
     513             :                         status,
     514             :                         NT_STATUS_INVALID_PARAMETER,
     515             :                         talloc_asprintf(tctx, "create of %s should return "
     516             :                                 "NT_STATUS_INVALID_PARAMETER, got %s",
     517             :                         fname,
     518             :                         smbcli_errstr(cli1->tree)));
     519             : 
     520             :                 /* This should fail - the file should not have been created. */
     521          28 :                 status = smbcli_getatr(cli1->tree, fname, NULL, NULL, NULL);
     522          28 :                 torture_assert_ntstatus_equal(tctx,
     523             :                         status,
     524             :                         NT_STATUS_OBJECT_NAME_NOT_FOUND,
     525             :                         talloc_asprintf(tctx, "getattr of %s succeeded should "
     526             :                                 "not have been created !",
     527             :                         fname));
     528             :         }
     529             : 
     530           6 :         return true;
     531             : }
     532             : 
     533             : /* Test 9a ... */
     534           7 : static bool deltest9a(struct torture_context *tctx,
     535             :                         struct smbcli_state *cli1,
     536             :                         struct smbcli_state *cli2)
     537             : {
     538           7 :         int fnum1 = -1;
     539           1 :         NTSTATUS status;
     540           7 :         uint32_t disps[4] = {
     541             :                         NTCREATEX_DISP_OVERWRITE_IF,
     542             :                         NTCREATEX_DISP_OPEN,
     543             :                         NTCREATEX_DISP_OVERWRITE,
     544             :                         NTCREATEX_DISP_OPEN_IF};
     545             : 
     546           1 :         unsigned int i;
     547             : 
     548           7 :         del_clean_area(cli1, cli2);
     549             : 
     550             :         /* Create the file, and try with open calls. */
     551           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_RDWR, DENY_NONE);
     552           7 :         torture_assert(tctx,
     553             :                         fnum1 != -1,
     554             :                         talloc_asprintf(tctx, "open of %s failed (%s)",
     555             :                         fname,
     556             :                         smbcli_errstr(cli1->tree)));
     557           7 :         status = smbcli_close(cli1->tree, fnum1);
     558           7 :         torture_assert_ntstatus_ok(tctx,
     559             :                                 status,
     560             :                                 talloc_asprintf(tctx, "close failed"));
     561             : 
     562          35 :         for (i = 0; i < sizeof(disps)/sizeof(disps[0]); i++) {
     563          28 :                 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     564             :                                 SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
     565             :                                 FILE_ATTRIBUTE_NORMAL,
     566             :                                 NTCREATEX_SHARE_ACCESS_NONE,
     567             :                                 disps[i],
     568             :                                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     569             : 
     570          28 :                 torture_assert(tctx, fnum1 == -1,
     571             :                         talloc_asprintf(tctx, "open of %s succeeded "
     572             :                                 "should have failed!",
     573             :                         fname));
     574             : 
     575             :                 /* Must fail with NT_STATUS_INVALID_PARAMETER. */
     576          28 :                 status = smbcli_nt_error(cli1->tree);
     577          28 :                 torture_assert_ntstatus_equal(tctx,
     578             :                         status,
     579             :                         NT_STATUS_INVALID_PARAMETER,
     580             :                         talloc_asprintf(tctx, "create of %s should return "
     581             :                                 "NT_STATUS_INVALID_PARAMETER, got %s",
     582             :                         fname,
     583             :                         smbcli_errstr(cli1->tree)));
     584             : 
     585             :                 /*
     586             :                  * This should succeed - the file should not have been deleted.
     587             :                  */
     588          28 :                 status = smbcli_getatr(cli1->tree, fname, NULL, NULL, NULL);
     589          28 :                 torture_assert_ntstatus_ok(tctx,
     590             :                         status,
     591             :                         talloc_asprintf(tctx, "getattr of %s failed %s",
     592             :                         fname,
     593             :                         smbcli_errstr(cli1->tree)));
     594             :         }
     595             : 
     596           7 :         del_clean_area(cli1, cli2);
     597           7 :         return true;
     598             : }
     599             : 
     600             : /* Test 10 ... */
     601           7 : static bool deltest10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     602             : {
     603           7 :         int fnum1 = -1;
     604             : 
     605           7 :         del_clean_area(cli1, cli2);
     606             : 
     607           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     608             :                                       SEC_FILE_READ_DATA|
     609             :                                       SEC_FILE_WRITE_DATA|
     610             :                                       SEC_STD_DELETE,
     611             :                                       FILE_ATTRIBUTE_NORMAL,
     612             :                                       NTCREATEX_SHARE_ACCESS_NONE,
     613             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     614             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     615           7 :         torture_assert(tctx, fnum1 != -1,
     616             :                 talloc_asprintf(tctx, "open of %s failed (%s)",
     617             :                        fname, smbcli_errstr(cli1->tree)));
     618             : 
     619             :         /* This should delete the file. */
     620           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     621             :                 talloc_asprintf(tctx, "close failed (%s)",
     622             :                        smbcli_errstr(cli1->tree)));
     623             : 
     624             :         /* This should fail.. */
     625           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     626           7 :         torture_assert(tctx, fnum1 == -1,
     627             :                                 talloc_asprintf(tctx, "open of %s succeeded should have been deleted on close !",
     628             :                        fname));
     629           6 :         return true;
     630             : }
     631             : 
     632             : /* Test 11 ... */
     633           7 : static bool deltest11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     634             : {
     635           7 :         int fnum1 = -1;
     636           1 :         NTSTATUS status;
     637             : 
     638           7 :         del_clean_area(cli1, cli2);
     639             : 
     640             :         /* test 11 - does having read only attribute still allow delete on close. */
     641             : 
     642           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     643             :                                       SEC_RIGHTS_FILE_ALL,
     644             :                                       FILE_ATTRIBUTE_READONLY,
     645             :                                       NTCREATEX_SHARE_ACCESS_NONE,
     646             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     647             : 
     648           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
     649             :                        fname, smbcli_errstr(cli1->tree)));
     650             : 
     651           7 :         status = smbcli_nt_delete_on_close(cli1->tree, fnum1, true);
     652             : 
     653           7 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_CANNOT_DELETE,
     654             :                 talloc_asprintf(tctx, "setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)", smbcli_errstr(cli1->tree)));
     655             : 
     656           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     657             :                 talloc_asprintf(tctx, "close failed (%s)",
     658             :                        smbcli_errstr(cli1->tree)));
     659             : 
     660           7 :         return true;
     661             : }
     662             : 
     663             : /* Test 12 ... */
     664           7 : static bool deltest12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     665             : {
     666           7 :         int fnum1 = -1;
     667           1 :         NTSTATUS status;
     668             : 
     669           7 :         del_clean_area(cli1, cli2);
     670             : 
     671             :         /* test 12 - does having read only attribute still allow delete on
     672             :          * close at time of open. */
     673             : 
     674           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     675             :                                       SEC_RIGHTS_FILE_ALL,
     676             :                                       FILE_ATTRIBUTE_READONLY,
     677             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     678             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     679             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     680             : 
     681           7 :         torture_assert(tctx, fnum1 == -1,
     682             :                  talloc_asprintf(tctx, "open of %s succeeded. Should fail with "
     683             :                        "NT_STATUS_CANNOT_DELETE.\n", fname));
     684             : 
     685           7 :         status = smbcli_nt_error(cli1->tree);
     686           7 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_CANNOT_DELETE,
     687             :                          talloc_asprintf(tctx, "setting delete_on_close on open should "
     688             :                                "fail with NT_STATUS_CANNOT_DELETE. Got %s "
     689             :                                "instead)",
     690             :                                smbcli_errstr(cli1->tree)));
     691             : 
     692           6 :         return true;
     693             : }
     694             : 
     695             : /* Test 13 ... */
     696           7 : static bool deltest13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     697             : {
     698           7 :         int fnum1 = -1;
     699           7 :         int fnum2 = -1;
     700           7 :         bool correct = true;
     701             : 
     702           7 :         del_clean_area(cli1, cli2);
     703             : 
     704             :         /* Test 13: Does resetting the delete on close flag affect a second
     705             :          * fd? */
     706             : 
     707           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     708             :                                       SEC_FILE_READ_DATA|
     709             :                                       SEC_FILE_WRITE_DATA|
     710             :                                       SEC_STD_DELETE,
     711             :                                       FILE_ATTRIBUTE_NORMAL,
     712             :                                       NTCREATEX_SHARE_ACCESS_READ|
     713             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     714             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     715             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     716             :                                       0, 0);
     717             : 
     718           7 :         torture_assert(tctx, fnum1 != -1,
     719             :                 talloc_asprintf(tctx, "open of %s failed (%s)",
     720             :                        fname, smbcli_errstr(cli1->tree)));
     721             : 
     722           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
     723             :                                       SEC_FILE_READ_DATA|
     724             :                                       SEC_FILE_WRITE_DATA|
     725             :                                       SEC_STD_DELETE,
     726             :                                       FILE_ATTRIBUTE_NORMAL,
     727             :                                       NTCREATEX_SHARE_ACCESS_READ|
     728             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     729             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     730             :                                       NTCREATEX_DISP_OPEN, 0, 0);
     731             : 
     732           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx,
     733             :                                 "open of %s failed (%s)",
     734             :                        fname, smbcli_errstr(cli2->tree)));
     735             : 
     736           7 :         torture_assert_ntstatus_ok(tctx,
     737             :                                                 smbcli_nt_delete_on_close(cli1->tree, fnum1,
     738             :                                                        true),
     739             :                  "setting delete_on_close on file failed !");
     740             : 
     741           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, true, __location__);
     742           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, true, __location__);
     743             : 
     744           7 :         torture_assert_ntstatus_ok(tctx, smbcli_nt_delete_on_close(cli2->tree, fnum2,
     745             :                                                        false),
     746             :                  "unsetting delete_on_close on file failed !");
     747             : 
     748           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
     749           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
     750             : 
     751           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     752             :                 talloc_asprintf(tctx, "close - 1 failed (%s)",
     753             :                        smbcli_errstr(cli1->tree)));
     754             : 
     755           7 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
     756             :                         talloc_asprintf(tctx, "close - 2 failed (%s)",
     757             :                        smbcli_errstr(cli2->tree)));
     758             : 
     759           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
     760             : 
     761           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed!",
     762             :                        fname));
     763             : 
     764           7 :         smbcli_close(cli1->tree, fnum1);
     765             : 
     766           7 :         return correct;
     767             : }
     768             : 
     769             : /* Test 14 ... */
     770           7 : static bool deltest14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     771             : {
     772           7 :         int dnum1 = -1;
     773           7 :         bool correct = true;
     774             : 
     775           7 :         del_clean_area(cli1, cli2);
     776             : 
     777             :         /* Test 14 -- directory */
     778             : 
     779           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
     780             :                                       SEC_FILE_READ_DATA|
     781             :                                       SEC_FILE_WRITE_DATA|
     782             :                                       SEC_STD_DELETE,
     783             :                                       FILE_ATTRIBUTE_DIRECTORY,
     784             :                                       NTCREATEX_SHARE_ACCESS_READ|
     785             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     786             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     787             :                                       NTCREATEX_DISP_CREATE, 0, 0);
     788           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s!",
     789             :                        dname, smbcli_errstr(cli1->tree)));
     790             : 
     791           7 :         correct &= check_delete_on_close(tctx, cli1, dnum1, dname, false, __location__);
     792           7 :         torture_assert_ntstatus_ok(tctx, smbcli_nt_delete_on_close(cli1->tree, dnum1, true),
     793             :                         "setting delete_on_close on file failed !");
     794           7 :         correct &= check_delete_on_close(tctx, cli1, dnum1, dname, true, __location__);
     795           7 :         smbcli_close(cli1->tree, dnum1);
     796             : 
     797             :         /* Now it should be gone... */
     798             : 
     799           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
     800             :                                       SEC_FILE_READ_DATA|
     801             :                                       SEC_FILE_WRITE_DATA|
     802             :                                       SEC_STD_DELETE,
     803             :                                       FILE_ATTRIBUTE_DIRECTORY,
     804             :                                       NTCREATEX_SHARE_ACCESS_READ|
     805             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     806             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     807             :                                       NTCREATEX_DISP_OPEN, 0, 0);
     808           7 :         torture_assert(tctx, dnum1 == -1, "setting delete_on_close on file succeeded !");
     809             : 
     810           6 :         return correct;
     811             : }
     812             : 
     813             : /* Test 15 ... */
     814           7 : static bool deltest15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     815             : {
     816           7 :         int fnum1 = -1;
     817           7 :         bool correct = true;
     818           7 :         int fnum2 = -1;
     819           1 :         NTSTATUS status;
     820             : 
     821           7 :         del_clean_area(cli1, cli2);
     822             : 
     823             :         /* Test 15: delete on close under rename */
     824             : 
     825           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
     826           7 :         smbcli_unlink(cli1->tree, fname);
     827           7 :         smbcli_unlink(cli1->tree, fname_new);
     828             : 
     829           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     830             :                                       SEC_FILE_READ_DATA,
     831             :                                       FILE_ATTRIBUTE_NORMAL,
     832             :                                       NTCREATEX_SHARE_ACCESS_READ|
     833             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     834             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     835             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     836             :                                       0, 0);
     837             : 
     838           7 :         torture_assert(tctx, fnum1 != -1,
     839             :                 talloc_asprintf(tctx, "open - 1 of %s failed (%s)", fname, smbcli_errstr(cli1->tree)));
     840             : 
     841           7 :         status = smbcli_rename(cli2->tree, fname, fname_new);
     842             : 
     843           7 :         torture_assert_ntstatus_ok(tctx, status, "renaming failed!");
     844             : 
     845           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname_new, 0,
     846             :                                       SEC_GENERIC_ALL,
     847             :                                       FILE_ATTRIBUTE_NORMAL,
     848             :                                       NTCREATEX_SHARE_ACCESS_READ|
     849             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     850             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     851             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     852             :                                       0, 0);
     853             : 
     854           7 :         torture_assert(tctx, fnum2 != -1,
     855             :                 talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
     856             :                        fname_new, smbcli_errstr(cli1->tree)));
     857             : 
     858           7 :         status = smbcli_nt_delete_on_close(cli2->tree, fnum2, true);
     859             : 
     860           7 :         torture_assert_ntstatus_ok(tctx, status,
     861             :                 "setting delete_on_close on file failed !");
     862             : 
     863           7 :         smbcli_close(cli2->tree, fnum2);
     864             : 
     865             :         /* The file should be around under the new name, there's a second
     866             :          * handle open */
     867             : 
     868           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname_new, true, __location__);
     869             : 
     870           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
     871             :                                       SEC_GENERIC_ALL,
     872             :                                       FILE_ATTRIBUTE_NORMAL,
     873             :                                       NTCREATEX_SHARE_ACCESS_READ|
     874             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     875             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     876             :                                       NTCREATEX_DISP_OVERWRITE_IF,
     877             :                                       0, 0);
     878             : 
     879           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
     880             :                        fname, smbcli_errstr(cli1->tree)));
     881             : 
     882           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
     883             : 
     884           7 :         smbcli_close(cli2->tree, fnum2);
     885           7 :         smbcli_close(cli1->tree, fnum1);
     886             : 
     887           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     888             :                                       SEC_FILE_READ_EA,
     889             :                                       FILE_ATTRIBUTE_NORMAL,
     890             :                                       NTCREATEX_SHARE_ACCESS_READ|
     891             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     892             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     893             :                                       NTCREATEX_DISP_OPEN,
     894             :                                       0, 0);
     895             : 
     896           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
     897             :                        fname, smbcli_errstr(cli1->tree)));
     898             : 
     899           7 :         smbcli_close(cli1->tree, fnum1);
     900             : 
     901           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname_new, 0,
     902             :                                       SEC_FILE_READ_EA,
     903             :                                       FILE_ATTRIBUTE_NORMAL,
     904             :                                       NTCREATEX_SHARE_ACCESS_READ|
     905             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     906             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     907             :                                       NTCREATEX_DISP_OPEN,
     908             :                                       0, 0);
     909             : 
     910           7 :         torture_assert(tctx, fnum1 == -1,
     911             :                 "smbcli_open succeeded, should have "
     912             :                        "failed");
     913             : 
     914           6 :         return correct;
     915             : }
     916             : 
     917             : /* Test 16 ... */
     918           7 : static bool deltest16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     919             : {
     920           7 :         int fnum1 = -1;
     921           7 :         int fnum2 = -1;
     922           7 :         bool correct = true;
     923             : 
     924           7 :         del_clean_area(cli1, cli2);
     925             : 
     926             :         /* Test 16. */
     927             : 
     928             :         /* Ensure the file doesn't already exist. */
     929           7 :         smbcli_close(cli1->tree, fnum1);
     930           7 :         smbcli_close(cli1->tree, fnum2);
     931           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
     932           7 :         smbcli_unlink(cli1->tree, fname);
     933             : 
     934             :         /* Firstly create with all access, but delete on close. */
     935           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
     936             :                                       SEC_RIGHTS_FILE_ALL,
     937             :                                       FILE_ATTRIBUTE_NORMAL,
     938             :                                       NTCREATEX_SHARE_ACCESS_READ|
     939             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     940             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     941             :                                       NTCREATEX_DISP_CREATE,
     942             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
     943             : 
     944           7 :         torture_assert (tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)", fname, smbcli_errstr(cli1->tree)));
     945             : 
     946             :         /* The delete on close bit is *not* reported as being set. */
     947           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
     948             : 
     949             :         /* The delete on close bit is *not* reported as being set. */
     950           7 :         correct &= check_delete_on_close(tctx, cli1, -1, fname, false, __location__);
     951           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, false, __location__);
     952             : 
     953             :         /* Now try opening again for read-only. */
     954           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
     955             :                                       SEC_RIGHTS_FILE_READ,
     956             :                                       FILE_ATTRIBUTE_NORMAL,
     957             :                                       NTCREATEX_SHARE_ACCESS_READ|
     958             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
     959             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
     960             :                                       NTCREATEX_DISP_OPEN,
     961             :                                       0, 0);
     962             : 
     963             :         /* Should work. */
     964           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
     965             :                       fname, smbcli_errstr(cli1->tree)));
     966             : 
     967           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
     968           7 :         correct &= check_delete_on_close(tctx, cli1, -1, fname, false, __location__);
     969           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
     970           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, false, __location__);
     971             : 
     972           7 :         smbcli_close(cli1->tree, fnum1);
     973             : 
     974           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, true, __location__);
     975           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, true, __location__);
     976             : 
     977           7 :         smbcli_close(cli2->tree, fnum2);
     978             : 
     979             :         /* And the file should be deleted ! */
     980           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     981           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail)",
     982             :                        fname));
     983             : 
     984           7 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     985             : 
     986           6 :         return correct;
     987             : }
     988             : 
     989             : /* Test 16 ... */
     990           7 : static bool deltest16a(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
     991             : {
     992           7 :         int fnum1 = -1;
     993           7 :         int fnum2 = -1;
     994           7 :         bool correct = true;
     995             : 
     996           7 :         del_clean_area(cli1, cli2);
     997             : 
     998             :         /* Test 16. */
     999             : 
    1000             :         /* Ensure the file doesn't already exist. */
    1001           7 :         smbcli_close(cli1->tree, fnum1);
    1002           7 :         smbcli_close(cli1->tree, fnum2);
    1003           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1004           7 :         smbcli_unlink(cli1->tree, fname);
    1005             : 
    1006             :         /* Firstly open and create with all access */
    1007           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1008             :                                       SEC_RIGHTS_FILE_ALL,
    1009             :                                       FILE_ATTRIBUTE_NORMAL,
    1010             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1011             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1012             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1013             :                                       NTCREATEX_DISP_CREATE,
    1014             :                                       0, 0);
    1015           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1016             :                        fname, smbcli_errstr(cli1->tree)));
    1017             : 
    1018             :         /* And close - just to create the file. */
    1019           7 :         smbcli_close(cli1->tree, fnum1);
    1020             : 
    1021             :         /* Firstly create with all access, but delete on close. */
    1022           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1023             :                                       SEC_RIGHTS_FILE_ALL,
    1024             :                                       FILE_ATTRIBUTE_NORMAL,
    1025             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1026             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1027             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1028             :                                       NTCREATEX_DISP_OPEN,
    1029             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1030             : 
    1031           7 :         torture_assert (tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)", fname, smbcli_errstr(cli1->tree)));
    1032             : 
    1033             :         /* The delete on close bit is *not* reported as being set. */
    1034           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1035             : 
    1036             :         /* The delete on close bit is *not* reported as being set. */
    1037           7 :         correct &= check_delete_on_close(tctx, cli1, -1, fname, false, __location__);
    1038           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, false, __location__);
    1039             : 
    1040             :         /* Now try opening again for read-only. */
    1041           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
    1042             :                                       SEC_RIGHTS_FILE_READ,
    1043             :                                       FILE_ATTRIBUTE_NORMAL,
    1044             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1045             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1046             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1047             :                                       NTCREATEX_DISP_OPEN,
    1048             :                                       0, 0);
    1049             : 
    1050             :         /* Should work. */
    1051           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1052             :                       fname, smbcli_errstr(cli1->tree)));
    1053             : 
    1054           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1055           7 :         correct &= check_delete_on_close(tctx, cli1, -1, fname, false, __location__);
    1056           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    1057           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, false, __location__);
    1058             : 
    1059           7 :         smbcli_close(cli1->tree, fnum1);
    1060             : 
    1061           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    1062           7 :         correct &= check_delete_on_close(tctx, cli2, -1, fname, false, __location__);
    1063             : 
    1064           7 :         smbcli_close(cli2->tree, fnum2);
    1065             : 
    1066             :         /* And the file should be deleted ! */
    1067           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1068           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
    1069             :                        fname, smbcli_errstr(cli1->tree)));
    1070             : 
    1071           2 :         smbcli_close(cli1->tree, fnum1);
    1072           2 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1073           2 :         smbcli_unlink(cli1->tree, fname);
    1074             : 
    1075           2 :         return correct;
    1076             : }
    1077             : 
    1078             : /* Test 17 ... */
    1079           7 : static bool deltest17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1080             : {
    1081           7 :         int fnum1 = -1;
    1082           7 :         int fnum2 = -1;
    1083           7 :         bool correct = true;
    1084             : 
    1085           7 :         del_clean_area(cli1, cli2);
    1086             : 
    1087             :         /* Test 17. */
    1088             : 
    1089             :         /* Ensure the file doesn't already exist. */
    1090           7 :         smbcli_close(cli1->tree, fnum1);
    1091           7 :         smbcli_close(cli1->tree, fnum2);
    1092           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1093           7 :         smbcli_unlink(cli1->tree, fname);
    1094             : 
    1095             :         /* Firstly open and create with all access */
    1096           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1097             :                                       SEC_RIGHTS_FILE_ALL,
    1098             :                                       FILE_ATTRIBUTE_NORMAL,
    1099             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1100             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1101             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1102             :                                       NTCREATEX_DISP_CREATE,
    1103             :                                       0, 0);
    1104           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1105             :                        fname, smbcli_errstr(cli1->tree)));
    1106             : 
    1107             :         /* And close - just to create the file. */
    1108           7 :         smbcli_close(cli1->tree, fnum1);
    1109             : 
    1110             :         /* Next open with all access, but add delete on close. */
    1111           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1112             :                                       SEC_RIGHTS_FILE_ALL,
    1113             :                                       FILE_ATTRIBUTE_NORMAL,
    1114             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1115             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1116             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1117             :                                       NTCREATEX_DISP_OPEN,
    1118             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1119             : 
    1120           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1121             :                        fname, smbcli_errstr(cli1->tree)));
    1122             : 
    1123             :         /* The delete on close bit is *not* reported as being set. */
    1124           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1125             : 
    1126             :         /* Now try opening again for read-only. */
    1127           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1128             :                                       SEC_RIGHTS_FILE_READ|
    1129             :                                       SEC_STD_DELETE,
    1130             :                                       FILE_ATTRIBUTE_NORMAL,
    1131             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1132             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1133             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1134             :                                       NTCREATEX_DISP_OPEN,
    1135             :                                       0, 0);
    1136             : 
    1137             :         /* Should work. */
    1138           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1139             :                        fname, smbcli_errstr(cli1->tree)));
    1140             : 
    1141             :         /* still not reported as being set on either */
    1142           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1143           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1144             : 
    1145           7 :         smbcli_close(cli1->tree, fnum1);
    1146             : 
    1147             :         /* After the first close, the files has the delete on close bit set. */
    1148           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, true, __location__);
    1149             : 
    1150           7 :         smbcli_close(cli1->tree, fnum2);
    1151             : 
    1152             :         /* Make sure the file has been deleted */
    1153           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1154           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s failed (should succeed) - %s",
    1155             :                        fname, smbcli_errstr(cli1->tree)));
    1156             : 
    1157           5 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1158             : 
    1159           4 :         return correct;
    1160             : }
    1161             : 
    1162             : /* Test 17a - like 17, but the delete on close handle is closed last */
    1163           7 : static bool deltest17a(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1164             : {
    1165           7 :         int fnum1 = -1;
    1166           7 :         int fnum2 = -1;
    1167           7 :         bool correct = true;
    1168             : 
    1169           7 :         del_clean_area(cli1, cli2);
    1170             : 
    1171             :         /* Ensure the file doesn't already exist. */
    1172           7 :         smbcli_close(cli1->tree, fnum1);
    1173           7 :         smbcli_close(cli1->tree, fnum2);
    1174           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1175           7 :         smbcli_unlink(cli1->tree, fname);
    1176             : 
    1177             :         /* Firstly open and create with all access */
    1178           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1179             :                                       SEC_RIGHTS_FILE_ALL,
    1180             :                                       FILE_ATTRIBUTE_NORMAL,
    1181             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1182             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1183             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1184             :                                       NTCREATEX_DISP_CREATE,
    1185             :                                       0, 0);
    1186           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1187             :                        fname, smbcli_errstr(cli1->tree)));
    1188             : 
    1189             :         /* And close - just to create the file. */
    1190           7 :         smbcli_close(cli1->tree, fnum1);
    1191             : 
    1192             :         /* Next open with all access, but add delete on close. */
    1193           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1194             :                                       SEC_RIGHTS_FILE_ALL,
    1195             :                                       FILE_ATTRIBUTE_NORMAL,
    1196             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1197             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1198             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1199             :                                       NTCREATEX_DISP_OPEN,
    1200             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1201             : 
    1202           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1203             :                        fname, smbcli_errstr(cli1->tree)));
    1204             : 
    1205             :         /* The delete on close bit is *not* reported as being set. */
    1206           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1207             : 
    1208             :         /* Now try opening again for read-only. */
    1209           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1210             :                                       SEC_RIGHTS_FILE_READ|
    1211             :                                       SEC_STD_DELETE,
    1212             :                                       FILE_ATTRIBUTE_NORMAL,
    1213             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1214             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1215             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1216             :                                       NTCREATEX_DISP_OPEN,
    1217             :                                       0, 0);
    1218             : 
    1219             :         /* Should work. */
    1220           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1221             :                        fname, smbcli_errstr(cli1->tree)));
    1222             : 
    1223             :         /* still not reported as being set on either */
    1224           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1225           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1226             : 
    1227           7 :         smbcli_close(cli1->tree, fnum2);
    1228             : 
    1229           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1230             : 
    1231           7 :         smbcli_close(cli1->tree, fnum1);
    1232             : 
    1233             :         /*
    1234             :          * The file is still there:
    1235             :          * The second open seems to have removed the initial
    1236             :          * delete on close flag from the first handle
    1237             :          */
    1238           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1239           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 3 of %s failed (%s)",
    1240             :                        fname, smbcli_errstr(cli1->tree)));
    1241             : 
    1242           2 :         smbcli_close(cli1->tree, fnum1);
    1243           2 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1244           2 :         smbcli_unlink(cli1->tree, fname);
    1245             : 
    1246           2 :         return correct;
    1247             : }
    1248             : 
    1249             : /* Test 17b - like 17a, but the initial delete on close is set on the second handle */
    1250           7 : static bool deltest17b(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1251             : {
    1252           7 :         int fnum1 = -1;
    1253           7 :         int fnum2 = -1;
    1254           7 :         bool correct = true;
    1255             : 
    1256           7 :         del_clean_area(cli1, cli2);
    1257             : 
    1258             :         /* Ensure the file doesn't already exist. */
    1259           7 :         smbcli_close(cli1->tree, fnum1);
    1260           7 :         smbcli_close(cli1->tree, fnum2);
    1261           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1262           7 :         smbcli_unlink(cli1->tree, fname);
    1263             : 
    1264             :         /* Firstly open and create with all access */
    1265           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1266             :                                       SEC_RIGHTS_FILE_ALL,
    1267             :                                       FILE_ATTRIBUTE_NORMAL,
    1268             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1269             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1270             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1271             :                                       NTCREATEX_DISP_CREATE,
    1272             :                                       0, 0);
    1273           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1274             :                        fname, smbcli_errstr(cli1->tree)));
    1275             : 
    1276             :         /* And close - just to create the file. */
    1277           7 :         smbcli_close(cli1->tree, fnum1);
    1278             : 
    1279             :         /* Next open with all access, but add delete on close. */
    1280           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1281             :                                       SEC_RIGHTS_FILE_ALL,
    1282             :                                       FILE_ATTRIBUTE_NORMAL,
    1283             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1284             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1285             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1286             :                                       NTCREATEX_DISP_OPEN,
    1287             :                                       0, 0);
    1288             : 
    1289           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1290             :                        fname, smbcli_errstr(cli1->tree)));
    1291             : 
    1292             :         /* The delete on close bit is *not* reported as being set. */
    1293           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1294             : 
    1295             :         /* Now try opening again for read-only. */
    1296           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1297             :                                       SEC_RIGHTS_FILE_READ|
    1298             :                                       SEC_STD_DELETE,
    1299             :                                       FILE_ATTRIBUTE_NORMAL,
    1300             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1301             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1302             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1303             :                                       NTCREATEX_DISP_OPEN,
    1304             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1305             : 
    1306             :         /* Should work. */
    1307           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1308             :                        fname, smbcli_errstr(cli1->tree)));
    1309             : 
    1310             :         /* still not reported as being set on either */
    1311           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1312           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1313             : 
    1314           7 :         smbcli_close(cli1->tree, fnum1);
    1315             : 
    1316           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1317             : 
    1318           7 :         smbcli_close(cli1->tree, fnum2);
    1319             : 
    1320             :         /* Make sure the file has been deleted */
    1321           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1322           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 3 of %s succeeded (should fail)",
    1323             :                        fname));
    1324             : 
    1325           5 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1326             : 
    1327           4 :         return correct;
    1328             : }
    1329             : 
    1330             : /* Test 17c - like 17, but the initial delete on close is set on the second handle */
    1331           7 : static bool deltest17c(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1332             : {
    1333           7 :         int fnum1 = -1;
    1334           7 :         int fnum2 = -1;
    1335           7 :         bool correct = true;
    1336             : 
    1337           7 :         del_clean_area(cli1, cli2);
    1338             : 
    1339             :         /* Ensure the file doesn't already exist. */
    1340           7 :         smbcli_close(cli1->tree, fnum1);
    1341           7 :         smbcli_close(cli1->tree, fnum2);
    1342           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1343           7 :         smbcli_unlink(cli1->tree, fname);
    1344             : 
    1345             :         /* Firstly open and create with all access */
    1346           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1347             :                                       SEC_RIGHTS_FILE_ALL,
    1348             :                                       FILE_ATTRIBUTE_NORMAL,
    1349             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1350             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1351             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1352             :                                       NTCREATEX_DISP_CREATE,
    1353             :                                       0, 0);
    1354           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1355             :                        fname, smbcli_errstr(cli1->tree)));
    1356             : 
    1357             :         /* And close - just to create the file. */
    1358           7 :         smbcli_close(cli1->tree, fnum1);
    1359             : 
    1360             :         /* Next open with all access, but add delete on close. */
    1361           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1362             :                                       SEC_RIGHTS_FILE_ALL,
    1363             :                                       FILE_ATTRIBUTE_NORMAL,
    1364             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1365             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1366             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1367             :                                       NTCREATEX_DISP_OPEN,
    1368             :                                       0, 0);
    1369             : 
    1370           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1371             :                        fname, smbcli_errstr(cli1->tree)));
    1372             : 
    1373             :         /* The delete on close bit is *not* reported as being set. */
    1374           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1375             : 
    1376             :         /* Now try opening again for read-only. */
    1377           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1378             :                                       SEC_RIGHTS_FILE_READ|
    1379             :                                       SEC_STD_DELETE,
    1380             :                                       FILE_ATTRIBUTE_NORMAL,
    1381             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1382             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1383             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1384             :                                       NTCREATEX_DISP_OPEN,
    1385             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1386             : 
    1387             :         /* Should work. */
    1388           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1389             :                        fname, smbcli_errstr(cli1->tree)));
    1390             : 
    1391             :         /* still not reported as being set on either */
    1392           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1393           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1394             : 
    1395           7 :         smbcli_close(cli1->tree, fnum2);
    1396             : 
    1397           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, true, __location__);
    1398             : 
    1399           7 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1400           7 :         torture_assert(tctx, fnum2 == -1, talloc_asprintf(tctx, "open - 3 of %s succeeded (should fail)",
    1401             :                        fname));
    1402             : 
    1403           7 :         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
    1404             : 
    1405           5 :         smbcli_close(cli1->tree, fnum1);
    1406             : 
    1407             :         /* Make sure the file has been deleted */
    1408           5 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1409           5 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 4 of %s succeeded (should fail)",
    1410             :                        fname));
    1411             : 
    1412           5 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1413             : 
    1414           4 :         return correct;
    1415             : }
    1416             : 
    1417             : /* Test 17d - like 17a, but the first delete-on-close opener creates the file */
    1418           7 : static bool deltest17d(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1419             : {
    1420           7 :         int fnum1 = -1;
    1421           7 :         int fnum2 = -1;
    1422           7 :         bool correct = true;
    1423             : 
    1424           7 :         del_clean_area(cli1, cli2);
    1425             : 
    1426             :         /* Ensure the file doesn't already exist. */
    1427           7 :         smbcli_close(cli1->tree, fnum1);
    1428           7 :         smbcli_close(cli1->tree, fnum2);
    1429           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1430           7 :         smbcli_unlink(cli1->tree, fname);
    1431             : 
    1432             : 
    1433             :         /* Create the file with delete on close. */
    1434           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1435             :                                       SEC_RIGHTS_FILE_ALL,
    1436             :                                       FILE_ATTRIBUTE_NORMAL,
    1437             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1438             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1439             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1440             :                                       NTCREATEX_DISP_CREATE,
    1441             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1442             : 
    1443           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1444             :                        fname, smbcli_errstr(cli1->tree)));
    1445             : 
    1446             :         /* The delete on close bit is *not* reported as being set. */
    1447           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1448             : 
    1449             :         /* Now try opening again for read-only. */
    1450           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1451             :                                       SEC_RIGHTS_FILE_READ|
    1452             :                                       SEC_STD_DELETE,
    1453             :                                       FILE_ATTRIBUTE_NORMAL,
    1454             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1455             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1456             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1457             :                                       NTCREATEX_DISP_OPEN,
    1458             :                                       0, 0);
    1459             : 
    1460             :         /* Should work. */
    1461           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1462             :                        fname, smbcli_errstr(cli1->tree)));
    1463             : 
    1464             :         /* still not reported as being set on either */
    1465           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1466           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1467             : 
    1468           7 :         smbcli_close(cli1->tree, fnum2);
    1469             : 
    1470           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1471             : 
    1472           7 :         smbcli_close(cli1->tree, fnum1);
    1473             : 
    1474             :         /*
    1475             :          * The file is still there:
    1476             :          * The second open seems to have removed the initial
    1477             :          * delete on close flag from the first handle
    1478             :          */
    1479           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1480           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 3 of %s succeed (should fail)",
    1481             :                        fname));
    1482             : 
    1483           7 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1484             : 
    1485           6 :         return correct;
    1486             : }
    1487             : 
    1488           7 : static bool deltest17e(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1489             : {
    1490           7 :         int fnum1 = -1;
    1491           7 :         int fnum2 = -1;
    1492           7 :         int fnum3 = -1;
    1493           7 :         bool correct = true;
    1494             : 
    1495           7 :         del_clean_area(cli1, cli2);
    1496             : 
    1497             :         /* Ensure the file doesn't already exist. */
    1498           7 :         smbcli_close(cli1->tree, fnum1);
    1499           7 :         smbcli_close(cli1->tree, fnum2);
    1500           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1501           7 :         smbcli_unlink(cli1->tree, fname);
    1502             : 
    1503             :         /* Firstly open and create with all access */
    1504           7 :         fnum3 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1505             :                                       SEC_RIGHTS_FILE_ALL,
    1506             :                                       FILE_ATTRIBUTE_NORMAL,
    1507             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1508             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1509             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1510             :                                       NTCREATEX_DISP_CREATE,
    1511             :                                       0, 0);
    1512           7 :         torture_assert(tctx, fnum3 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1513             :                        fname, smbcli_errstr(cli1->tree)));
    1514             : 
    1515             :         /* Next open with all access, but add delete on close. */
    1516           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1517             :                                       SEC_RIGHTS_FILE_ALL,
    1518             :                                       FILE_ATTRIBUTE_NORMAL,
    1519             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1520             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1521             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1522             :                                       NTCREATEX_DISP_OPEN,
    1523             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1524             : 
    1525           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1526             :                        fname, smbcli_errstr(cli1->tree)));
    1527             : 
    1528             :         /* The delete on close bit is *not* reported as being set. */
    1529           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1530           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, false, __location__);
    1531             : 
    1532             :         /* Now try opening again for read-only. */
    1533           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1534             :                                       SEC_RIGHTS_FILE_READ|
    1535             :                                       SEC_STD_DELETE,
    1536             :                                       FILE_ATTRIBUTE_NORMAL,
    1537             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1538             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1539             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1540             :                                       NTCREATEX_DISP_OPEN,
    1541             :                                       0, 0);
    1542             : 
    1543             :         /* Should work. */
    1544           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 3 of %s failed (%s)",
    1545             :                        fname, smbcli_errstr(cli1->tree)));
    1546             : 
    1547             :         /* still not reported as being set on either */
    1548           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1549           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1550           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, false, __location__);
    1551             : 
    1552           7 :         smbcli_close(cli1->tree, fnum1);
    1553             : 
    1554             :         /*
    1555             :          * closing the handle that has delete_on_close set
    1556             :          * inherits the flag to the global context
    1557             :          */
    1558           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, true, __location__);
    1559           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, true, __location__);
    1560             : 
    1561           7 :         smbcli_close(cli1->tree, fnum2);
    1562             : 
    1563           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, true, __location__);
    1564             : 
    1565           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1566           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 4 of %s succeeded (should fail)",
    1567             :                        fname));
    1568             : 
    1569           7 :         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
    1570             : 
    1571           5 :         smbcli_close(cli1->tree, fnum3);
    1572             : 
    1573           5 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1574           5 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 5 of %s succeeded (should fail)",
    1575             :                        fname));
    1576             : 
    1577           5 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1578             : 
    1579           4 :         return correct;
    1580             : }
    1581             : 
    1582           7 : static bool deltest17f(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1583             : {
    1584           7 :         int fnum1 = -1;
    1585           7 :         int fnum2 = -1;
    1586           7 :         int fnum3 = -1;
    1587           7 :         bool correct = true;
    1588           1 :         NTSTATUS status;
    1589             : 
    1590           7 :         del_clean_area(cli1, cli2);
    1591             : 
    1592             :         /* Ensure the file doesn't already exist. */
    1593           7 :         smbcli_close(cli1->tree, fnum1);
    1594           7 :         smbcli_close(cli1->tree, fnum2);
    1595           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1596           7 :         smbcli_unlink(cli1->tree, fname);
    1597             : 
    1598             :         /* Firstly open and create with all access */
    1599           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1600             :                                       SEC_RIGHTS_FILE_ALL,
    1601             :                                       FILE_ATTRIBUTE_NORMAL,
    1602             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1603             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1604             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1605             :                                       NTCREATEX_DISP_CREATE,
    1606             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1607           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1608             :                        fname, smbcli_errstr(cli1->tree)));
    1609             : 
    1610             :         /* The delete on close bit is *not* reported as being set. */
    1611           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1612             : 
    1613             :         /* Next open with all access, but add delete on close. */
    1614           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1615             :                                       SEC_RIGHTS_FILE_ALL,
    1616             :                                       FILE_ATTRIBUTE_NORMAL,
    1617             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1618             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1619             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1620             :                                       NTCREATEX_DISP_OPEN,
    1621             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1622             : 
    1623           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1624             :                        fname, smbcli_errstr(cli1->tree)));
    1625             : 
    1626             :         /* still not reported as being set on either */
    1627           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1628           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1629             : 
    1630             :         /* Now try opening again for read-only. */
    1631           7 :         fnum3 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1632             :                                       SEC_RIGHTS_FILE_READ|
    1633             :                                       SEC_STD_DELETE,
    1634             :                                       FILE_ATTRIBUTE_NORMAL,
    1635             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1636             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1637             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1638             :                                       NTCREATEX_DISP_OPEN,
    1639             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1640             : 
    1641             :         /* Should work. */
    1642           7 :         torture_assert(tctx, fnum3 != -1, talloc_asprintf(tctx, "open - 3 of %s failed (%s)",
    1643             :                        fname, smbcli_errstr(cli1->tree)));
    1644             : 
    1645             :         /* still not reported as being set on either */
    1646           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1647           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1648           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, false, __location__);
    1649             : 
    1650           7 :         smbcli_close(cli1->tree, fnum1);
    1651             : 
    1652             :         /*
    1653             :          * closing the handle that has delete_on_close set
    1654             :          * inherits the flag to the global context
    1655             :          */
    1656           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, true, __location__);
    1657           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, true, __location__);
    1658             : 
    1659             : 
    1660           7 :         status = smbcli_nt_delete_on_close(cli1->tree, fnum2, false);
    1661           7 :         torture_assert_ntstatus_ok(tctx, status,
    1662             :                                         "clearing delete_on_close on file failed !");
    1663             : 
    1664           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, fname, false, __location__);
    1665           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, false, __location__);
    1666             : 
    1667           7 :         smbcli_close(cli1->tree, fnum2);
    1668             : 
    1669           7 :         correct &= check_delete_on_close(tctx, cli1, fnum3, fname, true, __location__);
    1670             : 
    1671           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1672           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 4 of %s succeeded (should fail)",
    1673             :                        fname));
    1674             : 
    1675           7 :         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
    1676             : 
    1677           5 :         smbcli_close(cli1->tree, fnum3);
    1678             : 
    1679           5 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1680           5 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open - 5 of %s succeeded (should fail)",
    1681             :                        fname));
    1682             : 
    1683           5 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1684             : 
    1685           4 :         return correct;
    1686             : }
    1687             : 
    1688             : /* Test 18 ... */
    1689           7 : static bool deltest18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1690             : {
    1691           7 :         int fnum1 = -1;
    1692           7 :         int fnum2 = -1;
    1693           7 :         bool correct = true;
    1694             : 
    1695           7 :         del_clean_area(cli1, cli2);
    1696             : 
    1697             :         /* Test 18. With directories. */
    1698             : 
    1699             :         /* Ensure the file doesn't already exist. */
    1700           7 :         smbcli_close(cli1->tree, fnum1);
    1701           7 :         smbcli_close(cli1->tree, fnum2);
    1702             : 
    1703           7 :         smbcli_deltree(cli1->tree, dname);
    1704             : 
    1705             :         /* Firstly create with all access, but delete on close. */
    1706           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1707             :                                       SEC_FILE_READ_DATA|
    1708             :                                       SEC_FILE_WRITE_DATA|
    1709             :                                       SEC_STD_DELETE,
    1710             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1711             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1712             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1713             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1714             :                                       NTCREATEX_DISP_CREATE,
    1715             :                                       NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1716             : 
    1717           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1718             :                        dname, smbcli_errstr(cli1->tree)));
    1719             : 
    1720             :         /*
    1721             :          * The delete on close bit is *not* reported as being set.
    1722             :          * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
    1723             :          * close as being set.  This causes the subsequent create to fail with
    1724             :          * NT_STATUS_DELETE_PENDING.
    1725             :          */
    1726           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, dname, false, __location__);
    1727             : 
    1728             :         /* Now try opening again for read-only. */
    1729           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1730             :                                       SEC_RIGHTS_FILE_READ,
    1731             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1732             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1733             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1734             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1735             :                                       NTCREATEX_DISP_OPEN,
    1736             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1737             : 
    1738             : 
    1739             :         /* Should work. */
    1740           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1741             :                        dname, smbcli_errstr(cli1->tree)));
    1742             : 
    1743           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, dname, false, __location__);
    1744           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, dname, false, __location__);
    1745             : 
    1746           7 :         smbcli_close(cli1->tree, fnum1);
    1747             : 
    1748           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, dname, true, __location__);
    1749             : 
    1750           7 :         smbcli_close(cli1->tree, fnum2);
    1751             : 
    1752             :         /* And the directory should be deleted ! */
    1753           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1754             :                                       SEC_RIGHTS_FILE_READ,
    1755             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1756             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1757             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1758             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1759             :                                       NTCREATEX_DISP_OPEN,
    1760             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1761           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail)",
    1762             :                        dname));
    1763             : 
    1764           6 :         return correct;
    1765             : }
    1766             : 
    1767             : /* Test 19 ... */
    1768           7 : static bool deltest19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1769             : {
    1770           7 :         int fnum1 = -1;
    1771           7 :         int fnum2 = -1;
    1772           7 :         bool correct = true;
    1773             : 
    1774           7 :         del_clean_area(cli1, cli2);
    1775             : 
    1776             :         /* Test 19. */
    1777             : 
    1778           7 :         smbcli_deltree(cli1->tree, dname);
    1779             : 
    1780             :         /* Firstly open and create with all access */
    1781           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1782             :                                       SEC_FILE_READ_DATA|
    1783             :                                       SEC_FILE_WRITE_DATA|
    1784             :                                       SEC_STD_DELETE,
    1785             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1786             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1787             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1788             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1789             :                                       NTCREATEX_DISP_CREATE,
    1790             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1791             : 
    1792           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1793             :                        dname, smbcli_errstr(cli1->tree)));
    1794             : 
    1795             :         /* And close - just to create the directory. */
    1796           7 :         smbcli_close(cli1->tree, fnum1);
    1797             : 
    1798             :         /* Next open with all access, but add delete on close. */
    1799           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1800             :                                       SEC_FILE_READ_DATA|
    1801             :                                       SEC_FILE_WRITE_DATA|
    1802             :                                       SEC_STD_DELETE,
    1803             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1804             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1805             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1806             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1807             :                                       NTCREATEX_DISP_OPEN,
    1808             :                                       NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1809             : 
    1810           7 :         torture_assert(tctx, fnum1 != -1,
    1811             :                 talloc_asprintf(tctx, "open - 1 of %s failed (%s)", fname, smbcli_errstr(cli1->tree)));
    1812             : 
    1813             :         /*
    1814             :          * The delete on close bit is *not* reported as being set.
    1815             :          * Win2k3/win2k8 should pass this check, but WinXPsp2 reports delete on
    1816             :          * close as being set.  This causes the subsequent create to fail with
    1817             :          * NT_STATUS_DELETE_PENDING.
    1818             :          */
    1819           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, dname, false, __location__);
    1820             : 
    1821             :         /* Now try opening again for read-only. */
    1822           7 :         fnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1823             :                                       SEC_RIGHTS_FILE_READ,
    1824             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1825             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1826             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1827             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1828             :                                       NTCREATEX_DISP_OPEN,
    1829             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1830             : 
    1831             :         /* Should work. */
    1832           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1833             :                        dname, smbcli_errstr(cli1->tree)));
    1834             : 
    1835           7 :         smbcli_close(cli1->tree, fnum1);
    1836             : 
    1837           7 :         correct &= check_delete_on_close(tctx, cli1, fnum2, dname, true, __location__);
    1838             : 
    1839           7 :         smbcli_close(cli1->tree, fnum2);
    1840             : 
    1841             :         /* See if the file is deleted - for a directory this seems to be true ! */
    1842           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1843             :                                       SEC_RIGHTS_FILE_READ,
    1844             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1845             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1846             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1847             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1848             :                                       NTCREATEX_DISP_OPEN,
    1849             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1850             : 
    1851           7 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1852             : 
    1853           7 :         torture_assert(tctx, fnum1 == -1,
    1854             :                 talloc_asprintf(tctx, "open of %s succeeded (should fail)", dname));
    1855             : 
    1856           6 :         return correct;
    1857             : }
    1858             : 
    1859             : /* Test 20 ... */
    1860           7 : static bool deltest20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1861             : {
    1862           7 :         int fnum1 = -1;
    1863           7 :         int dnum1 = -1;
    1864           7 :         bool correct = true;
    1865           1 :         NTSTATUS status;
    1866           1 :         int ret;
    1867             : 
    1868           7 :         if (geteuid() == 0) {
    1869           0 :                 torture_skip(tctx, "This test doesn't work as user root.");
    1870             :         }
    1871             : 
    1872           7 :         del_clean_area(cli1, cli2);
    1873             : 
    1874             :         /* Test 20 -- non-empty directory hardest to get right... */
    1875             : 
    1876           7 :         smbcli_deltree(cli1->tree, dname);
    1877             : 
    1878           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    1879             :                                       SEC_FILE_READ_DATA|
    1880             :                                       SEC_FILE_WRITE_DATA|
    1881             :                                       SEC_STD_DELETE,
    1882             :                                       FILE_ATTRIBUTE_DIRECTORY,
    1883             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1884             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1885             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1886             :                                       NTCREATEX_DISP_CREATE,
    1887             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    1888           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s!",
    1889             :                        dname, smbcli_errstr(cli1->tree)));
    1890             : 
    1891           7 :         correct &= check_delete_on_close(tctx, cli1, dnum1, dname, false, __location__);
    1892           7 :         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, true);
    1893             : 
    1894             :         {
    1895           1 :                 char *fullname;
    1896           7 :                 ret = asprintf(&fullname, "\\%s%s", dname, fname);
    1897           7 :                 torture_assert(tctx, ret != -1, "asprintf failed");
    1898           7 :                 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
    1899             :                                     DENY_NONE);
    1900           7 :                 torture_assert(tctx, fnum1 == -1,
    1901             :                                 "smbcli_open succeeded, should have "
    1902             :                                "failed with NT_STATUS_DELETE_PENDING"
    1903             :                                );
    1904             : 
    1905           7 :                 torture_assert_ntstatus_equal(tctx,
    1906             :                                          smbcli_nt_error(cli1->tree),
    1907             :                                      NT_STATUS_DELETE_PENDING,
    1908             :                                         "smbcli_open failed");
    1909             :         }
    1910             : 
    1911           7 :         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, false);
    1912           7 :         torture_assert_ntstatus_ok(tctx, status,
    1913             :                                         "unsetting delete_on_close on file failed !");
    1914             : 
    1915             :         {
    1916           1 :                 char *fullname;
    1917           7 :                 ret = asprintf(&fullname, "\\%s%s", dname, fname);
    1918           7 :                 torture_assert(tctx, ret != -1, "asprintf failed");
    1919           7 :                 fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR,
    1920             :                                     DENY_NONE);
    1921           7 :                 torture_assert(tctx, fnum1 != -1,
    1922             :                                 talloc_asprintf(tctx, "smbcli_open failed: %s\n",
    1923             :                                smbcli_errstr(cli1->tree)));
    1924           7 :                 smbcli_close(cli1->tree, fnum1);
    1925             :         }
    1926             : 
    1927           7 :         status = smbcli_nt_delete_on_close(cli1->tree, dnum1, true);
    1928             : 
    1929           7 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_DIRECTORY_NOT_EMPTY,
    1930             :                  "setting delete_on_close failed");
    1931           7 :         smbcli_close(cli1->tree, dnum1);
    1932             : 
    1933           7 :         return correct;
    1934             : }
    1935             : 
    1936             : /* Test 20a ... */
    1937           7 : static bool deltest20a(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    1938             : {
    1939           7 :         int fnum1 = -1;
    1940           7 :         int fnum2 = -1;
    1941           7 :         bool correct = true;
    1942             : 
    1943           7 :         del_clean_area(cli1, cli2);
    1944             : 
    1945             :         /* Test 20a. */
    1946             : 
    1947             :         /* Ensure the file doesn't already exist. */
    1948           7 :         smbcli_close(cli1->tree, fnum1);
    1949           7 :         smbcli_close(cli1->tree, fnum2);
    1950           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    1951           7 :         smbcli_unlink(cli1->tree, fname);
    1952             : 
    1953             :         /* Firstly open and create with all access */
    1954           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1955             :                                       SEC_RIGHTS_FILE_ALL,
    1956             :                                       FILE_ATTRIBUTE_NORMAL,
    1957             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1958             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1959             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1960             :                                       NTCREATEX_DISP_CREATE,
    1961             :                                       0, 0);
    1962           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    1963             :                        fname, smbcli_errstr(cli1->tree)));
    1964             : 
    1965             :         /* Next open with all access, but add delete on close. */
    1966           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
    1967             :                                       SEC_RIGHTS_FILE_ALL,
    1968             :                                       FILE_ATTRIBUTE_NORMAL,
    1969             :                                       NTCREATEX_SHARE_ACCESS_READ|
    1970             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    1971             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    1972             :                                       NTCREATEX_DISP_OPEN,
    1973             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    1974             : 
    1975           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    1976             :                        fname, smbcli_errstr(cli2->tree)));
    1977             : 
    1978             :         /* The delete on close bit is *not* reported as being set. */
    1979           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    1980           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    1981             : 
    1982           7 :         smbcli_close(cli1->tree, fnum1);
    1983             : 
    1984           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    1985             : 
    1986           7 :         smbcli_close(cli2->tree, fnum2);
    1987             : 
    1988             :         /* See if the file is deleted - should be.... */
    1989           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    1990           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail) - %s",
    1991             :                        fname, smbcli_errstr(cli1->tree)));
    1992             : 
    1993           4 :         return correct;
    1994             : }
    1995             : 
    1996             : /* Test 20b ... */
    1997             : /* This is the delete semantics that the cifsfs client depends on when
    1998             :  * trying to delete an open file on a Windows server. It
    1999             :  * opens a file with initial delete on close set, renames it then closes
    2000             :  * all open handles. The file goes away on Windows.
    2001             :  */
    2002             : 
    2003           7 : static bool deltest20b(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2004             : {
    2005           7 :         int fnum1 = -1;
    2006           7 :         int fnum2 = -1;
    2007           7 :         bool correct = true;
    2008             : 
    2009           7 :         del_clean_area(cli1, cli2);
    2010             : 
    2011             :         /* Test 20b. */
    2012             : 
    2013             :         /* Ensure the file doesn't already exist. */
    2014           7 :         smbcli_close(cli1->tree, fnum1);
    2015           7 :         smbcli_close(cli1->tree, fnum2);
    2016           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
    2017           7 :         smbcli_unlink(cli1->tree, fname);
    2018           7 :         smbcli_setatr(cli1->tree, fname_new, 0, 0);
    2019           7 :         smbcli_unlink(cli1->tree, fname_new);
    2020             : 
    2021             :         /* Firstly open and create with all access */
    2022           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2023             :                                       SEC_RIGHTS_FILE_ALL,
    2024             :                                       FILE_ATTRIBUTE_NORMAL,
    2025             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2026             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2027             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2028             :                                       NTCREATEX_DISP_CREATE,
    2029             :                                       0, 0);
    2030           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    2031             :                        fname, smbcli_errstr(cli1->tree)));
    2032             : 
    2033             :         /* And close - just to create the file. */
    2034           7 :         smbcli_close(cli1->tree, fnum1);
    2035             : 
    2036             :         /* Firstly open and create with all access */
    2037           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2038             :                                       SEC_RIGHTS_FILE_ALL,
    2039             :                                       FILE_ATTRIBUTE_NORMAL,
    2040             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2041             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2042             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2043             :                                       NTCREATEX_DISP_OPEN,
    2044             :                                       0, 0);
    2045           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open - 1 of %s failed (%s)",
    2046             :                        fname, smbcli_errstr(cli1->tree)));
    2047             : 
    2048             :         /* Next open with all access, but add delete on close. */
    2049           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0,
    2050             :                                       SEC_RIGHTS_FILE_ALL,
    2051             :                                       FILE_ATTRIBUTE_NORMAL,
    2052             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2053             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2054             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2055             :                                       NTCREATEX_DISP_OPEN,
    2056             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    2057             : 
    2058           7 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, "open - 2 of %s failed (%s)",
    2059             :                        fname, smbcli_errstr(cli2->tree)));
    2060             : 
    2061             :         /* The delete on close bit is *not* reported as being set. */
    2062           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, false, __location__);
    2063           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    2064             : 
    2065           7 :         smbcli_close(cli1->tree, fnum1);
    2066             : 
    2067           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname, false, __location__);
    2068             : 
    2069             :         /* Rename the file by handle. */
    2070             : 
    2071             :         {
    2072           1 :                 union smb_setfileinfo sfinfo;
    2073           1 :                 NTSTATUS status;
    2074             : 
    2075           7 :                 memset(&sfinfo, '\0', sizeof(sfinfo));
    2076           7 :                 sfinfo.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
    2077           7 :                 sfinfo.generic.in.file.fnum = fnum2;
    2078           7 :                 sfinfo.rename_information.in.root_fid  = 0;
    2079             :                 /* Don't start the filename with '\\', we get NT_STATUS_NOT_SUPPORTED if so. */
    2080           7 :                 sfinfo.rename_information.in.new_name  = fname_new + 1;
    2081           7 :                 sfinfo.rename_information.in.overwrite = 1;
    2082             : 
    2083           7 :                 status = smb_raw_setfileinfo(cli2->tree, &sfinfo);
    2084             : 
    2085           7 :                 torture_assert_ntstatus_equal(tctx,status,NT_STATUS_OK,talloc_asprintf(tctx, "rename of %s to %s failed (%s)",
    2086             :                         fname, fname_new, smbcli_errstr(cli2->tree)));
    2087             :         }
    2088             : 
    2089           7 :         correct &= check_delete_on_close(tctx, cli2, fnum2, fname_new, false, __location__);
    2090             : 
    2091           7 :         smbcli_close(cli2->tree, fnum2);
    2092             : 
    2093             :         /* See if the file is deleted - should be.... */
    2094           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
    2095           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail) - %s",
    2096             :                        fname, smbcli_errstr(cli1->tree)));
    2097           7 :         fnum1 = smbcli_open(cli1->tree, fname_new, O_RDWR, DENY_NONE);
    2098           7 :         torture_assert(tctx, fnum1 == -1, talloc_asprintf(tctx, "open of %s succeeded (should fail) - %s",
    2099             :                        fname_new, smbcli_errstr(cli1->tree)));
    2100             : 
    2101           4 :         return correct;
    2102             : }
    2103             : 
    2104             : /* Test 20c */
    2105             : /* Along the lines of deltest20 we try to open a non-empty directory with delete
    2106             :  * on close set and subsequent close to verify its presence in the tree.
    2107             :  */
    2108           7 : static bool deltest20c(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
    2109             : {
    2110           7 :         int fnum1 = -1;
    2111           7 :         int dnum1 = -1;
    2112           1 :         int ret;
    2113           1 :         char *fullname;
    2114             : 
    2115           7 :         del_clean_area(cli1, cli2);
    2116             : 
    2117           7 :         smbcli_deltree(cli1->tree, dname);
    2118             : 
    2119             :         /* Firstly open and create with all access */
    2120           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2121             :                                       SEC_FILE_READ_DATA|
    2122             :                                       SEC_FILE_WRITE_DATA|
    2123             :                                       SEC_STD_DELETE,
    2124             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2125             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2126             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2127             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2128             :                                       NTCREATEX_DISP_CREATE,
    2129             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2130           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s",
    2131             :                        dname, smbcli_errstr(cli1->tree)));
    2132             : 
    2133             :         /* And close - just to create the directory */
    2134           7 :         smbcli_close(cli1->tree, dnum1);
    2135             : 
    2136           7 :         ret = asprintf(&fullname, "\\%s%s", dname, fname);
    2137           7 :         torture_assert(tctx, ret != -1, "asprintf failed");
    2138             : 
    2139             :         /* Open and create with all access */
    2140           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fullname, 0,
    2141             :                                       SEC_RIGHTS_FILE_ALL,
    2142             :                                       FILE_ATTRIBUTE_NORMAL,
    2143             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2144             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2145             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2146             :                                       NTCREATEX_DISP_CREATE,
    2147             :                                       0, 0);
    2148           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s",
    2149             :                        fname, smbcli_errstr(cli1->tree)));
    2150             : 
    2151             :         /* And close - just to create the file. */
    2152           7 :         smbcli_close(cli1->tree, fnum1);
    2153             : 
    2154             :         /* Open with all access, but add delete on close */
    2155           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2156             :                                       SEC_FILE_READ_DATA|
    2157             :                                       SEC_FILE_WRITE_DATA|
    2158             :                                       SEC_STD_DELETE,
    2159             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2160             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2161             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2162             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2163             :                                       NTCREATEX_DISP_OPEN,
    2164             :                                       NTCREATEX_OPTIONS_DIRECTORY|NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    2165             :         /* Should work */
    2166           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s",
    2167             :                        dname, smbcli_errstr(cli1->tree)));
    2168             : 
    2169           7 :         smbcli_close(cli1->tree, dnum1);
    2170             : 
    2171             :         /* Try to open again */
    2172           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2173             :                                       SEC_FILE_READ_DATA|
    2174             :                                       SEC_FILE_WRITE_DATA|
    2175             :                                       SEC_STD_DELETE,
    2176             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2177             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2178             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2179             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2180             :                                       NTCREATEX_DISP_OPEN,
    2181             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2182             :         /* Directory should be still present*/
    2183           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx, "open of %s failed: %s",
    2184             :                        dname, smbcli_errstr(cli1->tree)));
    2185             : 
    2186           7 :         smbcli_close(cli1->tree, dnum1);
    2187             : 
    2188           7 :         return true;
    2189             : }
    2190             : 
    2191             : /* Test 21 ... */
    2192           7 : static bool deltest21(struct torture_context *tctx)
    2193             : {
    2194           7 :         int fnum1 = -1;
    2195           1 :         struct smbcli_state *cli1;
    2196           1 :         struct smbcli_state *cli2;
    2197           7 :         bool correct = true;
    2198             : 
    2199           7 :         if (!torture_open_connection(&cli1, tctx, 0))
    2200           0 :                 return false;
    2201             : 
    2202           7 :         if (!torture_open_connection(&cli2, tctx, 1))
    2203           0 :                 return false;
    2204             : 
    2205           7 :         del_clean_area(cli1, cli2);
    2206             : 
    2207             :         /* Test 21 -- Test removal of file after socket close. */
    2208             : 
    2209           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2210             :                                       SEC_RIGHTS_FILE_ALL,
    2211             :                                       FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
    2212             :                                       NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    2213             : 
    2214           7 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, "open of %s failed (%s)",
    2215             :                        fname, smbcli_errstr(cli1->tree)));
    2216             : 
    2217           7 :         torture_assert_ntstatus_ok(tctx,
    2218             :                                 smbcli_nt_delete_on_close(cli1->tree, fnum1, true),
    2219             :                                 talloc_asprintf(tctx, "setting delete_on_close failed (%s)",
    2220             :                        smbcli_errstr(cli1->tree)));
    2221             : 
    2222             :         /* Ensure delete on close is set. */
    2223           7 :         correct &= check_delete_on_close(tctx, cli1, fnum1, fname, true, __location__);
    2224             : 
    2225             :         /* Now yank the rug from under cli1. */
    2226           7 :         smbcli_transport_dead(cli1->transport, NT_STATUS_LOCAL_DISCONNECT);
    2227             : 
    2228           7 :         fnum1 = -1;
    2229             : 
    2230           7 :         if (!torture_open_connection(&cli1, tctx, 0)) {
    2231           0 :                 return false;
    2232             :         }
    2233             : 
    2234             :         /* On slow build farm machines it might happen that they are not fast
    2235             :          * enough to delete the file for this test */
    2236           7 :         smb_msleep(200);
    2237             : 
    2238             :         /* File should not be there. */
    2239           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2240             :                                       SEC_RIGHTS_FILE_READ,
    2241             :                                       FILE_ATTRIBUTE_NORMAL,
    2242             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2243             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2244             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2245             :                                       NTCREATEX_DISP_OPEN,
    2246             :                                       0, 0);
    2247             : 
    2248           7 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    2249             : 
    2250           6 :         return correct;
    2251             : }
    2252             : 
    2253             : /* Test 22 ... */
    2254             : 
    2255             : /*
    2256             :  * Test whether a second *directory* handle inhibits delete if the first has
    2257             :  * del-on-close set and is closed
    2258             :  */
    2259           7 : static bool deltest22(struct torture_context *tctx)
    2260             : {
    2261           7 :         int dnum1 = -1;
    2262           7 :         int dnum2 = -1;
    2263           1 :         struct smbcli_state *cli1;
    2264           7 :         bool correct = true;
    2265             : 
    2266           7 :         if (!torture_open_connection(&cli1, tctx, 0))
    2267           0 :                 return false;
    2268             : 
    2269           7 :         smbcli_deltree(cli1->tree, dname);
    2270             : 
    2271           7 :         torture_assert_ntstatus_ok(
    2272             :                 tctx, smbcli_mkdir(cli1->tree, dname),
    2273             :                 talloc_asprintf(tctx, "smbcli_mdir failed: (%s)\n",
    2274             :                                 smbcli_errstr(cli1->tree)));
    2275             : 
    2276           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2277             :                                       SEC_FILE_READ_DATA|
    2278             :                                       SEC_FILE_WRITE_DATA|
    2279             :                                       SEC_STD_DELETE,
    2280             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2281             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2282             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2283             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2284             :                                       NTCREATEX_DISP_OPEN,
    2285             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2286             : 
    2287           7 :         torture_assert(tctx, dnum1 != -1,
    2288             :                        talloc_asprintf(tctx, "open of %s failed: %s!",
    2289             :                                        dname, smbcli_errstr(cli1->tree)));
    2290             : 
    2291           7 :         dnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2292             :                                       SEC_FILE_READ_DATA|
    2293             :                                       SEC_FILE_WRITE_DATA,
    2294             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2295             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2296             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2297             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2298             :                                       NTCREATEX_DISP_OPEN,
    2299             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2300             : 
    2301           7 :         torture_assert(tctx, dnum2 != -1,
    2302             :                        talloc_asprintf(tctx, "open of %s failed: %s!",
    2303             :                                        dname, smbcli_errstr(cli1->tree)));
    2304             : 
    2305           7 :         torture_assert_ntstatus_ok(
    2306             :                 tctx, smbcli_nt_delete_on_close(cli1->tree, dnum1, true),
    2307             :                 talloc_asprintf(tctx, "setting delete_on_close failed (%s)",
    2308             :                                 smbcli_errstr(cli1->tree)));
    2309             : 
    2310           7 :         smbcli_close(cli1->tree, dnum1);
    2311             : 
    2312           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2313             :                                       SEC_FILE_READ_DATA|
    2314             :                                       SEC_FILE_WRITE_DATA|
    2315             :                                       SEC_STD_DELETE,
    2316             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2317             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2318             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2319             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2320             :                                       NTCREATEX_DISP_OPEN,
    2321             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2322             : 
    2323           7 :         torture_assert(tctx, dnum1 == -1,
    2324             :                        talloc_asprintf(tctx, "open of %s succeeded!\n",
    2325             :                                        dname));
    2326             : 
    2327           7 :         CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
    2328             : 
    2329           7 :         smbcli_close(cli1->tree, dnum2);
    2330           7 :         CHECK_STATUS(cli1, NT_STATUS_OK);
    2331             : 
    2332           6 :         return correct;
    2333             : }
    2334             : 
    2335             : /* Test 23 - Second directory open fails when delete is pending. */
    2336           7 : static bool deltest23(struct torture_context *tctx,
    2337             :                         struct smbcli_state *cli1,
    2338             :                         struct smbcli_state *cli2)
    2339             : {
    2340           7 :         int dnum1 = -1;
    2341           7 :         int dnum2 = -1;
    2342           7 :         bool correct = true;
    2343             : 
    2344           7 :         del_clean_area(cli1, cli2);
    2345             : 
    2346             :         /* Test 23 -- Basic delete on close for directories. */
    2347             : 
    2348             :         /* Open a directory */
    2349           7 :         dnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2350             :                                       SEC_FILE_READ_DATA|
    2351             :                                       SEC_FILE_WRITE_DATA|
    2352             :                                       SEC_STD_DELETE,
    2353             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2354             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2355             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2356             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2357             :                                       NTCREATEX_DISP_CREATE,
    2358             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2359             : 
    2360           7 :         torture_assert(tctx, dnum1 != -1, talloc_asprintf(tctx,
    2361             :                            "open of %s failed: %s!",
    2362             :                            dname, smbcli_errstr(cli1->tree)));
    2363             : 
    2364           7 :         correct &= check_delete_on_close(tctx, cli1, dnum1, dname, false,
    2365             :             __location__);
    2366             : 
    2367             :         /* Set delete on close */
    2368           7 :         (void)smbcli_nt_delete_on_close(cli1->tree, dnum1, true);
    2369             : 
    2370             :         /* Attempt opening the directory again.  It should fail. */
    2371           7 :         dnum2 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2372             :                                       SEC_FILE_READ_DATA|
    2373             :                                       SEC_FILE_WRITE_DATA|
    2374             :                                       SEC_STD_DELETE,
    2375             :                                       FILE_ATTRIBUTE_DIRECTORY,
    2376             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2377             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2378             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2379             :                                       NTCREATEX_DISP_OPEN,
    2380             :                                       NTCREATEX_OPTIONS_DIRECTORY, 0);
    2381             : 
    2382           7 :         torture_assert(tctx, dnum2 == -1, talloc_asprintf(tctx,
    2383             :                            "open of %s succeeded: %s. It should have failed "
    2384             :                            "with NT_STATUS_DELETE_PENDING",
    2385             :                            dname, smbcli_errstr(cli1->tree)));
    2386             : 
    2387           7 :         torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree),
    2388             :             NT_STATUS_DELETE_PENDING, "smbcli_open failed");
    2389             : 
    2390           7 :         return correct;
    2391             : }
    2392             : 
    2393             : /* Test 24 ... */
    2394             : 
    2395             : /*
    2396             :  * Test whether unsetting delete-on-close before the close has any effect.
    2397             :  * It should be ignored.
    2398             :  */
    2399           7 : static bool deltest24(struct torture_context *tctx)
    2400             : {
    2401           7 :         int fnum1 = -1;
    2402           1 :         struct smbcli_state *cli1;
    2403           7 :         bool correct = true;
    2404             : 
    2405           7 :         if (!torture_open_connection(&cli1, tctx, 0))
    2406           0 :                 return false;
    2407             : 
    2408           7 :         smbcli_deltree(cli1->tree, fname);
    2409             : 
    2410           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2411             :                                       SEC_FILE_READ_DATA|
    2412             :                                       SEC_FILE_WRITE_DATA|
    2413             :                                       SEC_STD_DELETE,
    2414             :                                       FILE_ATTRIBUTE_NORMAL,
    2415             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2416             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2417             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2418             :                                       NTCREATEX_DISP_CREATE,
    2419             :                                       NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    2420             : 
    2421           7 :         torture_assert(tctx, fnum1 != -1,
    2422             :                        talloc_asprintf(tctx, "open of %s failed: %s!",
    2423             :                                        fname, smbcli_errstr(cli1->tree)));
    2424             : 
    2425             :         /* Now, unset Delete-On-Close, but it should have no effect */
    2426           7 :         torture_assert_ntstatus_ok(
    2427             :                 tctx, smbcli_nt_delete_on_close(cli1->tree, fnum1, false),
    2428             :                 talloc_asprintf(tctx, "unsetting delete_on_close failed (%s)",
    2429             :                                 smbcli_errstr(cli1->tree)));
    2430             : 
    2431           7 :         smbcli_close(cli1->tree, fnum1);
    2432             : 
    2433             :         /* File should not be there. */
    2434           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    2435             :                                       SEC_RIGHTS_FILE_READ,
    2436             :                                       FILE_ATTRIBUTE_NORMAL,
    2437             :                                       NTCREATEX_SHARE_ACCESS_READ|
    2438             :                                       NTCREATEX_SHARE_ACCESS_WRITE|
    2439             :                                       NTCREATEX_SHARE_ACCESS_DELETE,
    2440             :                                       NTCREATEX_DISP_OPEN,
    2441             :                                       0, 0);
    2442             : 
    2443           7 :         CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    2444             : 
    2445           6 :         return correct;
    2446             : }
    2447             : 
    2448             : /* Test 25 ... */
    2449           7 : static bool deltest25(struct torture_context *tctx,
    2450             :                         struct smbcli_state *cli1,
    2451             :                         struct smbcli_state *cli2)
    2452             : {
    2453           7 :         int fnum1 = -1;
    2454           1 :         NTSTATUS status;
    2455           7 :         uint32_t disps[4] = {
    2456             :                         NTCREATEX_DISP_SUPERSEDE,
    2457             :                         NTCREATEX_DISP_OVERWRITE_IF,
    2458             :                         NTCREATEX_DISP_CREATE,
    2459             :                         NTCREATEX_DISP_OPEN_IF};
    2460           1 :         unsigned int i;
    2461             : 
    2462           7 :         del_clean_area(cli1, cli2);
    2463             : 
    2464          36 :         for (i = 0; i < sizeof(disps)/sizeof(disps[0]); i++) {
    2465             :                 /* This should fail - we need to set DELETE_ACCESS. */
    2466             : 
    2467             :                 /*
    2468             :                  * A file or directory create with DELETE_ON_CLOSE but
    2469             :                  * without DELETE_ACCESS should fail with
    2470             :                  * NT_STATUS_INVALID_PARAMETER.
    2471             :                  */
    2472             : 
    2473          28 :                 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2474             :                                 SEC_FILE_READ_DATA,
    2475             :                                 FILE_ATTRIBUTE_DIRECTORY,
    2476             :                                 NTCREATEX_SHARE_ACCESS_NONE,
    2477             :                                 disps[i],
    2478             :                                 NTCREATEX_OPTIONS_DIRECTORY|
    2479             :                                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    2480             : 
    2481          28 :                 torture_assert(tctx, fnum1 == -1,
    2482             :                         talloc_asprintf(tctx, "open of %s succeeded "
    2483             :                                 "should have failed!",
    2484             :                         dname));
    2485             : 
    2486             :                 /* Must fail with NT_STATUS_INVALID_PARAMETER. */
    2487          28 :                 status = smbcli_nt_error(cli1->tree);
    2488          28 :                 torture_assert_ntstatus_equal(tctx,
    2489             :                         status,
    2490             :                         NT_STATUS_INVALID_PARAMETER,
    2491             :                         talloc_asprintf(tctx, "create of %s should return "
    2492             :                                 "NT_STATUS_INVALID_PARAMETER, got %s",
    2493             :                         dname,
    2494             :                         smbcli_errstr(cli1->tree)));
    2495             : 
    2496             :                 /*
    2497             :                  * This should fail - the directory
    2498             :                  * should not have been created.
    2499             :                  */
    2500          28 :                 status = smbcli_getatr(cli1->tree, dname, NULL, NULL, NULL);
    2501          28 :                 torture_assert_ntstatus_equal(tctx,
    2502             :                         status,
    2503             :                         NT_STATUS_OBJECT_NAME_NOT_FOUND,
    2504             :                         talloc_asprintf(tctx, "getattr of %s succeeded should "
    2505             :                                 "not have been created !",
    2506             :                         dname));
    2507             :         }
    2508             : 
    2509           6 :         return true;
    2510             : }
    2511             : 
    2512             : /* Test 25a... */
    2513           7 : static bool deltest25a(struct torture_context *tctx,
    2514             :                 struct smbcli_state *cli1,
    2515             :                 struct smbcli_state *cli2)
    2516             : {
    2517           7 :         int fnum1 = -1;
    2518           1 :         NTSTATUS status;
    2519           7 :         uint32_t disps[4] = {
    2520             :                         NTCREATEX_DISP_OVERWRITE_IF,
    2521             :                         NTCREATEX_DISP_OPEN,
    2522             :                         NTCREATEX_DISP_OVERWRITE,
    2523             :                         NTCREATEX_DISP_OPEN_IF};
    2524             : 
    2525           1 :         unsigned int i;
    2526             : 
    2527           7 :         del_clean_area(cli1, cli2);
    2528             : 
    2529             :         /* Create the directory, and try with open calls. */
    2530           7 :         status = smbcli_mkdir(cli1->tree, dname);
    2531           7 :         torture_assert_ntstatus_ok(tctx,
    2532             :                 status,
    2533             :                 talloc_asprintf(tctx, "mkdir of %s failed %s",
    2534             :                 dname,
    2535             :                 smbcli_errstr(cli1->tree)));
    2536             : 
    2537          35 :         for (i = 0; i < sizeof(disps)/sizeof(disps[0]); i++) {
    2538          28 :                 fnum1 = smbcli_nt_create_full(cli1->tree, dname, 0,
    2539             :                                 SEC_FILE_READ_DATA,
    2540             :                                 FILE_ATTRIBUTE_DIRECTORY,
    2541             :                                 NTCREATEX_SHARE_ACCESS_NONE,
    2542             :                                 disps[i],
    2543             :                                 NTCREATEX_OPTIONS_DIRECTORY|
    2544             :                                 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
    2545             : 
    2546          28 :                 torture_assert(tctx, fnum1 == -1,
    2547             :                         talloc_asprintf(tctx, "open of %s succeeded "
    2548             :                                 "should have failed!",
    2549             :                         dname));
    2550             : 
    2551             :                 /* Must fail with NT_STATUS_INVALID_PARAMETER. */
    2552          28 :                 status = smbcli_nt_error(cli1->tree);
    2553          28 :                 torture_assert_ntstatus_equal(tctx,
    2554             :                         status,
    2555             :                         NT_STATUS_INVALID_PARAMETER,
    2556             :                         talloc_asprintf(tctx, "create of %s should return "
    2557             :                                 "NT_STATUS_INVALID_PARAMETER, got %s",
    2558             :                         dname,
    2559             :                         smbcli_errstr(cli1->tree)));
    2560             : 
    2561             :                 /*
    2562             :                  * This should succeed - the directory
    2563             :                  * should not have been deleted.
    2564             :                  */
    2565          28 :                 status = smbcli_getatr(cli1->tree, dname, NULL, NULL, NULL);
    2566          28 :                 torture_assert_ntstatus_ok(tctx,
    2567             :                         status,
    2568             :                         talloc_asprintf(tctx, "getattr of %s failed %s",
    2569             :                         fname,
    2570             :                         smbcli_errstr(cli1->tree)));
    2571             :         }
    2572             : 
    2573           7 :         del_clean_area(cli1, cli2);
    2574           7 :         return true;
    2575             : }
    2576             : 
    2577             : /*
    2578             :   Test delete on close semantics.
    2579             :  */
    2580        2354 : struct torture_suite *torture_test_delete(TALLOC_CTX *ctx)
    2581             : {
    2582        2354 :         struct torture_suite *suite = torture_suite_create(
    2583             :                 ctx, "delete");
    2584             : 
    2585        2354 :         torture_suite_add_2smb_test(suite, "deltest1", deltest1);
    2586        2354 :         torture_suite_add_2smb_test(suite, "deltest2", deltest2);
    2587        2354 :         torture_suite_add_2smb_test(suite, "deltest3", deltest3);
    2588        2354 :         torture_suite_add_2smb_test(suite, "deltest4", deltest4);
    2589        2354 :         torture_suite_add_2smb_test(suite, "deltest5", deltest5);
    2590        2354 :         torture_suite_add_2smb_test(suite, "deltest6", deltest6);
    2591        2354 :         torture_suite_add_2smb_test(suite, "deltest7", deltest7);
    2592        2354 :         torture_suite_add_2smb_test(suite, "deltest8", deltest8);
    2593        2354 :         torture_suite_add_2smb_test(suite, "deltest9", deltest9);
    2594        2354 :         torture_suite_add_2smb_test(suite, "deltest9a", deltest9a);
    2595        2354 :         torture_suite_add_2smb_test(suite, "deltest10", deltest10);
    2596        2354 :         torture_suite_add_2smb_test(suite, "deltest11", deltest11);
    2597        2354 :         torture_suite_add_2smb_test(suite, "deltest12", deltest12);
    2598        2354 :         torture_suite_add_2smb_test(suite, "deltest13", deltest13);
    2599        2354 :         torture_suite_add_2smb_test(suite, "deltest14", deltest14);
    2600        2354 :         torture_suite_add_2smb_test(suite, "deltest15", deltest15);
    2601        2354 :         torture_suite_add_2smb_test(suite, "deltest16", deltest16);
    2602        2354 :         torture_suite_add_2smb_test(suite, "deltest16a", deltest16a);
    2603        2354 :         torture_suite_add_2smb_test(suite, "deltest17", deltest17);
    2604        2354 :         torture_suite_add_2smb_test(suite, "deltest17a", deltest17a);
    2605        2354 :         torture_suite_add_2smb_test(suite, "deltest17b", deltest17b);
    2606        2354 :         torture_suite_add_2smb_test(suite, "deltest17c", deltest17c);
    2607        2354 :         torture_suite_add_2smb_test(suite, "deltest17d", deltest17d);
    2608        2354 :         torture_suite_add_2smb_test(suite, "deltest17e", deltest17e);
    2609        2354 :         torture_suite_add_2smb_test(suite, "deltest17f", deltest17f);
    2610        2354 :         torture_suite_add_2smb_test(suite, "deltest18", deltest18);
    2611        2354 :         torture_suite_add_2smb_test(suite, "deltest19", deltest19);
    2612        2354 :         torture_suite_add_2smb_test(suite, "deltest20", deltest20);
    2613        2354 :         torture_suite_add_2smb_test(suite, "deltest20a", deltest20a);
    2614        2354 :         torture_suite_add_2smb_test(suite, "deltest20b", deltest20b);
    2615        2354 :         torture_suite_add_2smb_test(suite, "deltest20c", deltest20c);
    2616        2354 :         torture_suite_add_simple_test(suite, "deltest21", deltest21);
    2617        2354 :         torture_suite_add_simple_test(suite, "deltest22", deltest22);
    2618        2354 :         torture_suite_add_2smb_test(suite, "deltest23", deltest23);
    2619        2354 :         torture_suite_add_simple_test(suite, "deltest24", deltest24);
    2620        2354 :         torture_suite_add_2smb_test(suite, "deltest25", deltest25);
    2621        2354 :         torture_suite_add_2smb_test(suite, "deltest25a", deltest25a);
    2622             : 
    2623        2354 :         return suite;
    2624             : }

Generated by: LCOV version 1.14