root/source4/torture/basic/delete.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_delete_on_close
  2. del_clean_area
  3. deltest1
  4. deltest2
  5. deltest3
  6. deltest4
  7. deltest5
  8. deltest6
  9. deltest7
  10. deltest8
  11. deltest9
  12. deltest10
  13. deltest11
  14. deltest12
  15. deltest13
  16. deltest14
  17. deltest15
  18. deltest16
  19. deltest17
  20. deltest18
  21. deltest19
  22. deltest20
  23. deltest20a
  24. deltest20b
  25. deltest21
  26. deltest22
  27. torture_test_delete

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

/* [<][>][^][v][top][bottom][index][help] */