r13370: Added deltest21 - pull the rug out from a connection by socket
[samba.git] / source / torture / basic / delete.c
index 00807f0420a8f11881d1616911be1136bee928b7..226e5a5aa485cb350fac8eddbfce9685ce57bd24 100644 (file)
@@ -26,6 +26,8 @@
 #include "system/filesys.h"
 #include "libcli/raw/libcliraw.h"
 
+#include "torture/raw/proto.h"
+
 static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
                                  const char *fname, BOOL expect_it)
 {
@@ -141,35 +143,30 @@ static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
                goto fail; \
        }} while (0)
 
-/*
-  Test delete on close semantics.
- */
-BOOL torture_test_delete(void)
-{
-       struct smbcli_state *cli1;
-       struct smbcli_state *cli2 = NULL;
-       const char *fname = "\\delete.file";
-       const char *fname_new = "\\delete.new";
-       const char *dirname = "\\delete.dir";
-       int fnum1 = -1;
-       int fnum2 = -1;
-       int dnum1 = -1;
-       BOOL correct = True;
-       NTSTATUS status;
-       
-       printf("starting delete test\n");
-       
-       if (!torture_open_connection(&cli1)) {
-               return False;
-       }
+const char *fname = "\\delete.file";
+const char *fname_new = "\\delete.new";
+const char *dirname = "\\delete.dir";
 
+static void del_clean_area(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
        smbcli_deltree(cli1->tree, dirname);
-
-       /* Test 1 - this should delete the file on close. */
-       
        smbcli_setatr(cli1->tree, fname, 0, 0);
        smbcli_unlink(cli1->tree, fname);
-       
+       smbcli_setatr(cli1->tree, fname_new, 0, 0);
+       smbcli_unlink(cli1->tree, fname_new);
+
+       smb_raw_exit(cli1->session);
+       smb_raw_exit(cli2->session);
+}
+
+/* Test 1 - this should delete the file on close. */
+
+static BOOL deltest1(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+
+       del_clean_area(cli1, cli2);
+
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_RIGHTS_FILE_ALL,
                                      FILE_ATTRIBUTE_NORMAL,
@@ -179,32 +176,33 @@ BOOL torture_test_delete(void)
        if (fnum1 == -1) {
                printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
        if (fnum1 != -1) {
                printf("(%s) open of %s succeeded (should fail)\n", 
                       __location__, fname);
-               correct = False;
-               goto fail;
+               return False;
        }
        
        printf("first delete on close test succeeded.\n");
-       
-       /* Test 2 - this should delete the file on close. */
-       
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
+       return True;
+}
+
+/* Test 2 - this should delete the file on close. */
+static BOOL deltest2(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+
+       del_clean_area(cli1, cli2);
+
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_RIGHTS_FILE_ALL,
                                      FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, 
@@ -213,22 +211,19 @@ BOOL torture_test_delete(void)
        if (fnum1 == -1) {
                printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
                printf("(%s) setting delete_on_close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
@@ -238,16 +233,22 @@ BOOL torture_test_delete(void)
                if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                        printf("(%s) close failed (%s)\n", 
                               __location__, smbcli_errstr(cli1->tree));
-                       correct = False;
-                       goto fail;
+                       return False;
                }
                smbcli_unlink(cli1->tree, fname);
-       } else
+       } else {
                printf("second delete on close test succeeded.\n");
-       
-       /* Test 3 - ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
+       }
+       return True;
+}
+
+/* Test 3 - ... */
+static BOOL deltest3(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+
+       del_clean_area(cli1, cli2);
 
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_RIGHTS_FILE_ALL,
@@ -258,8 +259,7 @@ BOOL torture_test_delete(void)
        if (fnum1 == -1) {
                printf("(%s) open - 1 of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        /* This should fail with a sharing violation - open for delete is only compatible
@@ -274,8 +274,7 @@ BOOL torture_test_delete(void)
        if (fnum2 != -1) {
                printf("(%s) open  - 2 of %s succeeded - should have failed.\n", 
                       __location__, fname);
-               correct = False;
-               goto fail;
+               return False;
        }
 
        /* This should succeed. */
@@ -289,29 +288,25 @@ BOOL torture_test_delete(void)
        if (fnum2 == -1) {
                printf("(%s) open  - 2 of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
                printf("(%s) setting delete_on_close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close 1 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
                printf("(%s) close 2 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        /* This should fail - file should no longer be there. */
@@ -325,19 +320,21 @@ BOOL torture_test_delete(void)
                               __location__, smbcli_errstr(cli1->tree));
                }
                smbcli_unlink(cli1->tree, fname);
-               correct = False;
-               goto fail;
-       } else
+               return False;
+       } else {
                printf("third delete on close test succeeded.\n");
-
-       /* Test 4 ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       status = smbcli_unlink(cli1->tree, fname);
-       if (NT_STATUS_IS_OK(status)) {
-               printf("(%s) succeeded unlink of %s\n", __location__, fname);
-               correct = False;
-               goto fail;
        }
+       return True;
+}
+
+/* Test 4 ... */
+static BOOL deltest4(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
 
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_FILE_READ_DATA  | 
@@ -350,8 +347,7 @@ BOOL torture_test_delete(void)
        if (fnum1 == -1) {
                printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        /* This should succeed. */
@@ -365,22 +361,19 @@ BOOL torture_test_delete(void)
        if (fnum2 == -1) {
                printf("(%s) open  - 2 of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
                printf("(%s) close - 1 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
                printf("(%s) setting delete_on_close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        /* This should fail - no more opens once delete on close set. */
@@ -392,30 +385,35 @@ BOOL torture_test_delete(void)
        if (fnum2 != -1) {
                printf("(%s) open  - 3 of %s succeeded ! Should have failed.\n",
                       __location__, fname );
-               correct = False;
-               goto fail;
+               return False;
        }
        CHECK_STATUS(cli1, NT_STATUS_DELETE_PENDING);
 
-       printf("fourth delete on close test succeeded.\n");
-       
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close - 2 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
-       /* Test 5 ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
+       printf("fourth delete on close test succeeded.\n");
+
+  fail:
+
+       return correct;
+}
+
+/* Test 5 ... */
+static BOOL deltest5(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+
+       del_clean_area(cli1, cli2);
+
        fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
                printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        /* This should fail - only allowed on NT opens with DELETE access. */
@@ -423,23 +421,26 @@ BOOL torture_test_delete(void)
        if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
                printf("(%s) setting delete_on_close on OpenX file succeeded - should fail !\n",
                       __location__);
-               correct = False;
-               goto fail;
+               return False;
        }
 
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close - 2 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
-       
+
        printf("fifth delete on close test succeeded.\n");
-       
-       /* Test 6 ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
+       return True;
+}
+
+/* Test 6 ... */
+static BOOL deltest6(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+
+       del_clean_area(cli1, cli2);
+
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                   SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA,
                                   FILE_ATTRIBUTE_NORMAL, 
@@ -451,8 +452,7 @@ BOOL torture_test_delete(void)
        if (fnum1 == -1) {
                printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
        
        /* This should fail - only allowed on NT opens with DELETE access. */
@@ -460,23 +460,27 @@ BOOL torture_test_delete(void)
        if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
                printf("(%s) setting delete_on_close on file with no delete access succeeded - should fail !\n",
                       __location__);
-               correct = False;
-               goto fail;
+               return False;
        }
 
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close - 2 failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        printf("sixth delete on close test succeeded.\n");
-       
-       /* Test 7 ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
+       return True;
+}
+
+/* Test 7 ... */
+static BOOL deltest7(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_FILE_READ_DATA  | 
                                      SEC_FILE_WRITE_DATA |
@@ -534,17 +538,20 @@ BOOL torture_test_delete(void)
        }
 
        printf("seventh delete on close test succeeded.\n");
-       
-       /* Test 7 ... */
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
-       if (!torture_open_connection(&cli2)) {
-               printf("(%s) failed to open second connection.\n",
-                      __location__);
-               correct = False;
-               goto fail;
-       }
+
+  fail:
+
+       return correct;
+}
+
+/* Test 8 ... */
+static BOOL deltest8(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
 
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_FILE_READ_DATA|
@@ -608,10 +615,22 @@ BOOL torture_test_delete(void)
        if (fnum1 != -1) {
                printf("(%s) open of %s succeeded should have been deleted on close !\n",
                       __location__, fname);
-               goto fail;
                correct = False;
-       } else
+       } else {
                printf("eighth delete on close test succeeded.\n");
+       }
+
+  fail:
+
+       return correct;
+}
+
+/* Test 9 ... */
+static BOOL deltest9(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+
+       del_clean_area(cli1, cli2);
 
        /* This should fail - we need to set DELETE_ACCESS. */
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
@@ -624,11 +643,20 @@ BOOL torture_test_delete(void)
        if (fnum1 != -1) {
                printf("(%s) open of %s succeeded should have failed!\n", 
                       __location__, fname);
-               correct = False;
-               goto fail;
+               return False;
        }
 
        printf("ninth delete on close test succeeded.\n");
+       return True;
+}
+
+/* Test 10 ... */
+static BOOL deltest10(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
 
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_FILE_READ_DATA|
@@ -658,15 +686,26 @@ BOOL torture_test_delete(void)
        if (fnum1 != -1) {
                printf("(%s) open of %s succeeded should have been deleted on close !\n",
                       __location__, fname);
-               goto fail;
                correct = False;
-       } else
+               goto fail;
+       } else {
                printf("tenth delete on close test succeeded.\n");
+       }
 
-       /* test 11 - does having read only attribute still allow delete on close. */
+  fail:
 
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
+       return correct;
+}
+
+/* Test 11 ... */
+static BOOL deltest11(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       NTSTATUS status;
+
+       del_clean_area(cli1, cli2);
+
+       /* test 11 - does having read only attribute still allow delete on close. */
 
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_RIGHTS_FILE_ALL,
@@ -677,8 +716,7 @@ BOOL torture_test_delete(void)
         if (fnum1 == -1) {
                 printf("(%s) open of %s failed (%s)\n", 
                       __location__, fname, smbcli_errstr(cli1->tree));
-                correct = False;
-                goto fail;
+               return False;
         }
 
        status = smbcli_nt_delete_on_close(cli1->tree, fnum1, True);
@@ -686,20 +724,26 @@ BOOL torture_test_delete(void)
        if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
                printf("(%s) setting delete_on_close should fail with NT_STATUS_CANNOT_DELETE. Got %s instead)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
        if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
                printf("(%s) close failed (%s)\n", 
                       __location__, smbcli_errstr(cli1->tree));
-               correct = False;
-               goto fail;
+               return False;
        }
 
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
         printf("eleventh delete on close test succeeded.\n");
+       return True;
+}
+
+/* Test 12 ... */
+static BOOL deltest12(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       NTSTATUS status;
+
+       del_clean_area(cli1, cli2);
 
        /* test 12 - does having read only attribute still allow delete on
         * close at time of open. */
@@ -715,8 +759,7 @@ BOOL torture_test_delete(void)
                printf("(%s) open of %s succeeded. Should fail with "
                       "NT_STATUS_CANNOT_DELETE.\n", __location__, fname);
                smbcli_close(cli1->tree, fnum1);
-               correct = False;
-               goto fail;
+               return False;
        } else {
                status = smbcli_nt_error(cli1->tree);
                if (!NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
@@ -724,19 +767,26 @@ BOOL torture_test_delete(void)
                               "fail with NT_STATUS_CANNOT_DELETE. Got %s "
                               "instead)\n", 
                               __location__, smbcli_errstr(cli1->tree));
-                       correct = False;
-                       goto fail;
+                       return False;
                }
        }
        
         printf("twelvth delete on close test succeeded.\n");
+       return True;
+}
+
+/* Test 13 ... */
+static BOOL deltest13(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
 
        /* Test 13: Does resetting the delete on close flag affect a second
         * fd? */
 
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
-       
        fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
                                      SEC_FILE_READ_DATA|
                                      SEC_FILE_WRITE_DATA|
@@ -817,11 +867,21 @@ BOOL torture_test_delete(void)
                goto fail;
        }
 
-       smbcli_close(cli1->tree, fnum1);
-       smbcli_unlink(cli1->tree, fname);
-
        printf("thirteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 14 ... */
+static BOOL deltest14(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int dnum1 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 14 -- directory */
 
        dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0,
@@ -870,6 +930,21 @@ BOOL torture_test_delete(void)
 
        printf("fourteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 15 ... */
+static BOOL deltest15(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+       NTSTATUS status;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 15: delete on close under rename */
 
        smbcli_setatr(cli1->tree, fname, 0, 0);
@@ -994,6 +1069,20 @@ BOOL torture_test_delete(void)
 
        printf("fifteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 16 ... */
+static BOOL deltest16(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 16. */
 
        /* Ensure the file doesn't already exist. */
@@ -1056,6 +1145,20 @@ BOOL torture_test_delete(void)
        
        printf("sixteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 17 ... */
+static BOOL deltest17(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 17. */
 
        /* Ensure the file doesn't already exist. */
@@ -1105,7 +1208,8 @@ BOOL torture_test_delete(void)
 
        /* Now try opening again for read-only. */
        fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, 
-                                     SEC_RIGHTS_FILE_READ,
+                                     SEC_RIGHTS_FILE_READ|
+                                     SEC_STD_DELETE,
                                      FILE_ATTRIBUTE_NORMAL,
                                      NTCREATEX_SHARE_ACCESS_READ|
                                      NTCREATEX_SHARE_ACCESS_WRITE|
@@ -1128,14 +1232,28 @@ BOOL torture_test_delete(void)
        /* See if the file is deleted - shouldn't be.... */
        fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
        if (fnum1 == -1) {
-               printf("(%s) open of %s failed (should succeed)\n", 
-                      __location__, fname);
+               printf("(%s) open of %s failed (should succeed) - %s\n", 
+                      __location__, fname, smbcli_errstr(cli1->tree));
                correct = False;
                goto fail;
        }
        
        printf("seventeenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 18 ... */
+static BOOL deltest18(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 18. With directories. */
 
        /* Ensure the file doesn't already exist. */
@@ -1207,6 +1325,20 @@ BOOL torture_test_delete(void)
        
        printf("eighteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 19 ... */
+static BOOL deltest19(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int fnum2 = -1;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 19. */
 
        smbcli_deltree(cli1->tree, dirname);
@@ -1256,7 +1388,7 @@ BOOL torture_test_delete(void)
        check_delete_on_close(cli1, fnum1, dirname, False);
 
        /* Now try opening again for read-only. */
-       fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
+       fnum2 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
                                      SEC_RIGHTS_FILE_READ,
                                      FILE_ATTRIBUTE_DIRECTORY,
                                      NTCREATEX_SHARE_ACCESS_READ|
@@ -1277,7 +1409,7 @@ BOOL torture_test_delete(void)
        smbcli_close(cli1->tree, fnum1);
        smbcli_close(cli1->tree, fnum2);
 
-       /* See if the file is deleted - shouldn't be.... */
+       /* See if the file is deleted - for a directory this seems to be true ! */
        fnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, 
                                      SEC_RIGHTS_FILE_READ,
                                      FILE_ATTRIBUTE_DIRECTORY,
@@ -1286,15 +1418,33 @@ BOOL torture_test_delete(void)
                                      NTCREATEX_SHARE_ACCESS_DELETE,
                                      NTCREATEX_DISP_OPEN,
                                      NTCREATEX_OPTIONS_DIRECTORY, 0);
-       if (fnum1 == -1) {
-               printf("(%s) open of %s failed (should succeed)\n", 
+
+       CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+       if (fnum1 != -1) {
+               printf("(%s) open of %s succeeded (should fail)\n", 
                       __location__, dirname);
                correct = False;
                goto fail;
        }
-       
+
        printf("nineteenth delete on close test succeeded.\n");
 
+  fail:
+
+       return correct;
+}
+
+/* Test 20 ... */
+static BOOL deltest20(struct smbcli_state *cli1, struct smbcli_state *cli2)
+{
+       int fnum1 = -1;
+       int dnum1 = -1;
+       BOOL correct = True;
+       NTSTATUS status;
+
+       del_clean_area(cli1, cli2);
+
        /* Test 20 -- non-empty directory hardest to get right... */
 
        smbcli_deltree(cli1->tree, dirname);
@@ -1378,19 +1528,125 @@ BOOL torture_test_delete(void)
 
        printf("twentieth delete on close test succeeded.\n");
 
-       printf("finished delete test\n");
+  fail:
+
+       return correct;
+}
+
+/* Test 21 ... */
+static BOOL deltest21(struct smbcli_state **ppcli1, struct smbcli_state **ppcli2)
+{
+       int fnum1 = -1;
+       struct smbcli_state *cli1 = *ppcli1;
+       struct smbcli_state *cli2 = *ppcli2;
+       BOOL correct = True;
+
+       del_clean_area(cli1, cli2);
+
+       /* Test 21 -- Test removal of file after socket close. */
+
+       fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
+                                     SEC_RIGHTS_FILE_ALL,
+                                     FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, 
+                                     NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
+       
+       if (fnum1 == -1) {
+               printf("(%s) open of %s failed (%s)\n", 
+                      __location__, fname, smbcli_errstr(cli1->tree));
+               return False;
+       }
+       
+       if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
+               printf("(%s) setting delete_on_close failed (%s)\n", 
+                      __location__, smbcli_errstr(cli1->tree));
+               return False;
+       }
+       
+       /* Ensure delete on close is set. */
+       check_delete_on_close(cli1, fnum1, fname, True);
+
+       /* Now yank the rug from under cli1. */
+       smbcli_transport_dead(cli1->transport);
+
+       fnum1 = -1;
+
+       if (!torture_open_connection(ppcli1)) {
+               return False;
+       }
+
+       cli1 = *ppcli1;
+
+       /* File should not be there. */
+       fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, 
+                                     SEC_RIGHTS_FILE_READ,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     NTCREATEX_SHARE_ACCESS_READ|
+                                     NTCREATEX_SHARE_ACCESS_WRITE|
+                                     NTCREATEX_SHARE_ACCESS_DELETE,
+                                     NTCREATEX_DISP_OPEN,
+                                     0, 0);
+       
+       CHECK_STATUS(cli1, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+       printf("twenty-first delete on close test succeeded.\n");
 
   fail:
-       /* FIXME: This will crash if we aborted before cli2 got
-        * intialized, because these functions don't handle
-        * uninitialized connections. */
-               
-       smbcli_close(cli1->tree, fnum1);
-       smbcli_close(cli1->tree, fnum2);
-       smbcli_setatr(cli1->tree, fname, 0, 0);
-       smbcli_unlink(cli1->tree, fname);
 
-       smbcli_deltree(cli1->tree, dirname);
+       return correct;
+}
+       
+/*
+  Test delete on close semantics.
+ */
+BOOL torture_test_delete(void)
+{
+       struct smbcli_state *cli1 = NULL;
+       struct smbcli_state *cli2 = NULL;
+       BOOL correct = True;
+       
+       printf("starting delete test\n");
+       
+       if (!torture_open_connection(&cli1)) {
+               return False;
+       }
+
+       if (!torture_open_connection(&cli2)) {
+               printf("(%s) failed to open second connection.\n",
+                      __location__);
+               correct = False;
+               goto fail;
+       }
+
+       correct &= deltest1(cli1, cli2);
+       correct &= deltest2(cli1, cli2);
+       correct &= deltest3(cli1, cli2);
+       correct &= deltest4(cli1, cli2);
+       correct &= deltest5(cli1, cli2);
+       correct &= deltest6(cli1, cli2);
+       correct &= deltest7(cli1, cli2);
+       correct &= deltest8(cli1, cli2);
+       correct &= deltest9(cli1, cli2);
+       correct &= deltest10(cli1, cli2);
+       correct &= deltest11(cli1, cli2);
+       correct &= deltest12(cli1, cli2);
+       correct &= deltest13(cli1, cli2);
+       correct &= deltest14(cli1, cli2);
+       correct &= deltest15(cli1, cli2);
+       correct &= deltest16(cli1, cli2);
+       correct &= deltest17(cli1, cli2);
+       correct &= deltest18(cli1, cli2);
+       correct &= deltest19(cli1, cli2);
+       correct &= deltest20(cli1, cli2);
+       correct &= deltest21(&cli1, &cli2);
+
+       if (!correct) {
+               printf("Failed delete test\n");
+       } else {
+               printf("delete test ok !\n");
+       }
+
+  fail:
+       del_clean_area(cli1, cli2);
 
        if (!torture_close_connection(cli1)) {
                correct = False;
@@ -1400,4 +1656,3 @@ BOOL torture_test_delete(void)
        }
        return correct;
 }
-