libsmb: Move cli_raw_ioctl() to torture3
[samba.git] / source3 / torture / torture.c
index b4ad36127f534ac912eabf29d76076e9664b58d8..bfce1c9dcd659df64c6d52b885678b7b082a8565 100644 (file)
@@ -51,6 +51,7 @@
 #include "lib/param/param.h"
 #include "auth/gensec/gensec.h"
 #include "lib/util/string_wrappers.h"
+#include "source3/lib/substitute.h"
 
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
@@ -452,6 +453,137 @@ bool torture_close_connection(struct cli_state *c)
        return ret;
 }
 
+void torture_conn_set_sockopt(struct cli_state *cli)
+{
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+}
+
+static NTSTATUS torture_delete_fn(struct file_info *finfo,
+                                 const char *pattern,
+                                 void *state)
+{
+       NTSTATUS status;
+       char *filename = NULL;
+       char *dirname = NULL;
+       char *p = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct cli_state *cli = (struct cli_state *)state;
+
+       if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_OK;
+       }
+
+       dirname = talloc_strdup(frame, pattern);
+       if (dirname == NULL) {
+               TALLOC_FREE(frame);
+                return NT_STATUS_NO_MEMORY;
+        }
+        p = strrchr_m(dirname, '\\');
+        if (p != NULL) {
+                /* Remove the terminating '\' */
+                *p = '\0';
+        }
+        if (dirname[0] != '\0') {
+                filename = talloc_asprintf(frame,
+                                           "%s\\%s",
+                                           dirname,
+                                           finfo->name);
+        } else {
+                filename = talloc_asprintf(frame,
+                                           "%s",
+                                           finfo->name);
+        }
+        if (filename == NULL) {
+                TALLOC_FREE(frame);
+                return NT_STATUS_NO_MEMORY;
+        }
+       if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
+               char *subdirname = talloc_asprintf(frame,
+                                                  "%s\\*",
+                                                  filename);
+               if (subdirname == NULL) {
+                       TALLOC_FREE(frame);
+                       return NT_STATUS_NO_MEMORY;
+               }
+               status = cli_list(cli,
+                                 subdirname,
+                                 FILE_ATTRIBUTE_DIRECTORY |
+                                         FILE_ATTRIBUTE_HIDDEN |
+                                         FILE_ATTRIBUTE_SYSTEM,
+                                 torture_delete_fn,
+                                 cli);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("torture_delete_fn: cli_list "
+                               "of %s failed (%s)\n",
+                               subdirname,
+                               nt_errstr(status));
+                       TALLOC_FREE(frame);
+                       return status;
+               }
+               status = cli_rmdir(cli, filename);
+       } else {
+               status = cli_unlink(cli,
+                                   filename,
+                                   FILE_ATTRIBUTE_SYSTEM |
+                                       FILE_ATTRIBUTE_HIDDEN);
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
+                       printf("torture_delete_fn: cli_rmdir"
+                               " of %s failed (%s)\n",
+                               filename,
+                               nt_errstr(status));
+               } else {
+                       printf("torture_delete_fn: cli_unlink"
+                               " of %s failed (%s)\n",
+                               filename,
+                               nt_errstr(status));
+               }
+       }
+       TALLOC_FREE(frame);
+       return status;
+}
+
+void torture_deltree(struct cli_state *cli, const char *dname)
+{
+       char *mask = NULL;
+       NTSTATUS status;
+
+       /* It might be a file */
+       (void)cli_unlink(cli,
+                        dname,
+                        FILE_ATTRIBUTE_SYSTEM |
+                               FILE_ATTRIBUTE_HIDDEN);
+
+       mask = talloc_asprintf(cli,
+                              "%s\\*",
+                              dname);
+       if (mask == NULL) {
+               printf("torture_deltree: talloc_asprintf failed\n");
+               return;
+       }
+
+       status = cli_list(cli,
+                       mask,
+                       FILE_ATTRIBUTE_DIRECTORY |
+                               FILE_ATTRIBUTE_HIDDEN|
+                               FILE_ATTRIBUTE_SYSTEM,
+                       torture_delete_fn,
+                       cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("torture_deltree: cli_list of %s failed (%s)\n",
+                       mask,
+                       nt_errstr(status));
+       }
+       TALLOC_FREE(mask);
+       status = cli_rmdir(cli, dname);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("torture_deltree: cli_rmdir of %s failed (%s)\n",
+                       dname,
+                       nt_errstr(status));
+       }
+}
 
 /* check if the server produced the expected dos or nt error code */
 static bool check_both_error(int line, NTSTATUS status,
@@ -524,6 +656,54 @@ static bool check_error(int line, NTSTATUS status,
        return True;
 }
 
+NTSTATUS cli_qpathinfo1(struct cli_state *cli,
+                       const char *fname,
+                       time_t *change_time,
+                       time_t *access_time,
+                       time_t *write_time,
+                       off_t *size,
+                       uint32_t *pattr)
+{
+       int timezone = smb1cli_conn_server_time_zone(cli->conn);
+       time_t (*date_fn)(const void *buf, int serverzone) = NULL;
+       uint8_t *rdata = NULL;
+       uint32_t num_rdata;
+       NTSTATUS status;
+
+       status = cli_qpathinfo(talloc_tos(),
+                              cli,
+                              fname,
+                              SMB_INFO_STANDARD,
+                              22,
+                              CLI_BUFFER_SIZE,
+                              &rdata,
+                              &num_rdata);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       if (cli->win95) {
+               date_fn = make_unix_date;
+       } else {
+               date_fn = make_unix_date2;
+       }
+
+       if (change_time) {
+               *change_time = date_fn(rdata + 0, timezone);
+       }
+       if (access_time) {
+               *access_time = date_fn(rdata + 4, timezone);
+       }
+       if (write_time) {
+               *write_time = date_fn(rdata + 8, timezone);
+       }
+       if (size) {
+               *size = PULL_LE_U32(rdata, 12);
+       }
+       if (pattr) {
+               *pattr = PULL_LE_U16(rdata, l1_attrFile);
+       }
+       return NT_STATUS_OK;
+}
 
 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
 {
@@ -1303,6 +1483,7 @@ static bool run_tcon_test(int dummy)
        uint16_t fnum1;
        uint32_t cnum1, cnum2, cnum3;
        struct smbXcli_tcon *orig_tcon = NULL;
+       char *orig_share = NULL;
        uint16_t vuid1, vuid2;
        char buf[4];
        bool ret = True;
@@ -1334,15 +1515,13 @@ static bool run_tcon_test(int dummy)
                return False;
        }
 
-       orig_tcon = cli_state_save_tcon(cli);
-       if (orig_tcon == NULL) {
-               return false;
-       }
+       cli_state_save_tcon_share(cli, &orig_tcon, &orig_share);
 
        status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
        if (!NT_STATUS_IS_OK(status)) {
                printf("%s refused 2nd tree connect (%s)\n", host,
                       nt_errstr(status));
+               cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
                cli_shutdown(cli);
                return False;
        }
@@ -1395,6 +1574,8 @@ static bool run_tcon_test(int dummy)
        status = cli_close(cli, fnum1);
        if (!NT_STATUS_IS_OK(status)) {
                printf("close failed (%s)\n", nt_errstr(status));
+               cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
+               cli_shutdown(cli);
                return False;
        }
 
@@ -1403,10 +1584,12 @@ static bool run_tcon_test(int dummy)
        status = cli_tdis(cli);
        if (!NT_STATUS_IS_OK(status)) {
                printf("secondary tdis failed (%s)\n", nt_errstr(status));
+               cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
+               cli_shutdown(cli);
                return False;
        }
 
-       cli_state_restore_tcon(cli, orig_tcon);
+       cli_state_restore_tcon_share(cli, orig_tcon, orig_share);
 
        cli_state_set_tid(cli, cnum1);
 
@@ -3816,8 +3999,15 @@ static bool run_negprot_nowait(int dummy)
        for (i=0;i<50000;i++) {
                struct tevent_req *req;
 
-               req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
-                                          PROTOCOL_CORE, PROTOCOL_NT1, 0);
+               req = smbXcli_negprot_send(
+                       ev,
+                       ev,
+                       cli->conn,
+                       cli->timeout,
+                       PROTOCOL_CORE,
+                       PROTOCOL_NT1,
+                       0,
+                       NULL);
                if (req == NULL) {
                        TALLOC_FREE(ev);
                        return false;
@@ -4196,6 +4386,50 @@ static bool run_attrtest(int dummy)
        return correct;
 }
 
+static NTSTATUS cli_qfilename(
+       struct cli_state *cli,
+       uint16_t fnum,
+       TALLOC_CTX *mem_ctx,
+       char **_name)
+{
+       uint16_t recv_flags2;
+       uint8_t *rdata;
+       uint32_t num_rdata;
+       NTSTATUS status;
+       char *name = NULL;
+       uint32_t namelen;
+
+       status = cli_qfileinfo(talloc_tos(), cli, fnum,
+                              SMB_QUERY_FILE_NAME_INFO,
+                              4, CLI_BUFFER_SIZE, &recv_flags2,
+                              &rdata, &num_rdata);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       namelen = IVAL(rdata, 0);
+       if (namelen > (num_rdata - 4)) {
+               TALLOC_FREE(rdata);
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+
+       pull_string_talloc(mem_ctx,
+                          (const char *)rdata,
+                          recv_flags2,
+                          &name,
+                          rdata + 4,
+                          namelen,
+                          STR_UNICODE);
+       if (name == NULL) {
+               status = map_nt_error_from_unix(errno);
+               TALLOC_FREE(rdata);
+               return status;
+       }
+
+       *_name = name;
+       TALLOC_FREE(rdata);
+       return NT_STATUS_OK;
+}
 
 /*
   This checks a couple of trans2 calls
@@ -4210,7 +4444,7 @@ static bool run_trans2test(int dummy)
        const char *fname = "\\trans2.tst";
        const char *dname = "\\trans2";
        const char *fname2 = "\\trans2\\trans2.tst";
-       char *pname;
+       char *pname = NULL;
        bool correct = True;
        NTSTATUS status;
        uint32_t fs_attr;
@@ -5660,7 +5894,7 @@ static bool run_deletetest(int dummy)
 
   fail:
        /* FIXME: This will crash if we aborted before cli2 got
-        * intialized, because these functions don't handle
+        * initialized, because these functions don't handle
         * uninitialized connections. */
 
        if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
@@ -5984,71 +6218,6 @@ static bool run_delete_print_test(int dummy)
        return correct;
 }
 
-/*
-  Test wildcard delete.
- */
-static bool run_wild_deletetest(int dummy)
-{
-       struct cli_state *cli = NULL;
-       const char *dname = "\\WTEST";
-       const char *fname = "\\WTEST\\A";
-       const char *wunlink_name = "\\WTEST\\*";
-       uint16_t fnum1 = (uint16_t)-1;
-       bool correct = false;
-       NTSTATUS status;
-
-       printf("starting wildcard delete test\n");
-
-       if (!torture_open_connection(&cli, 0)) {
-               return false;
-       }
-
-       smbXcli_conn_set_sockopt(cli->conn, sockops);
-
-       cli_unlink(cli, fname, 0);
-       cli_rmdir(cli, dname);
-       status = cli_mkdir(cli, dname);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
-               goto fail;
-       }
-       status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("open of %s failed %s!\n", fname, nt_errstr(status));
-               goto fail;
-       }
-       status = cli_close(cli, fnum1);
-       fnum1 = -1;
-
-       /*
-        * Note the unlink attribute-type of zero. This should
-        * map into FILE_ATTRIBUTE_NORMAL at the server even
-        * on a wildcard delete.
-        */
-
-       status = cli_unlink(cli, wunlink_name, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("unlink of %s failed %s!\n",
-                       wunlink_name, nt_errstr(status));
-               goto fail;
-       }
-
-       printf("finished wildcard delete test\n");
-
-       correct = true;
-
-  fail:
-
-       if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
-       cli_unlink(cli, fname, 0);
-       cli_rmdir(cli, dname);
-
-       if (cli && !torture_close_connection(cli)) {
-               correct = false;
-       }
-       return correct;
-}
-
 static bool run_deletetest_ln(int dummy)
 {
        struct cli_state *cli;
@@ -7642,6 +7811,7 @@ static bool run_simple_posix_open_test(int dummy)
        size_t nread;
        const char *fname_windows = "windows_file";
        uint16_t fnum2 = (uint16_t)-1;
+       bool ok;
 
        printf("Starting simple POSIX open test\n");
 
@@ -7910,18 +8080,19 @@ static bool run_simple_posix_open_test(int dummy)
        if (NT_STATUS_IS_OK(status)) {
                printf("POSIX open of %s succeeded (should have failed)\n", sname);
                goto out;
-       } else {
-               if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
-                               NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
-                       printf("POSIX open of %s should have failed "
-                               "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
-                               "failed with %s instead.\n",
-                               sname, nt_errstr(status));
-                       goto out;
-               }
+       }
+       ok = check_both_error(
+               __LINE__, status, ERRDOS, ERRbadpath,
+               NT_STATUS_OBJECT_NAME_NOT_FOUND);
+       if (!ok) {
+               printf("POSIX open of %s should have failed "
+                      "with NT_STATUS_OBJECT_NAME_NOT_FOUND, "
+                      "failed with %s instead.\n",
+                      sname, nt_errstr(status));
+               goto out;
        }
 
-       status = cli_posix_readlink(cli1, sname, talloc_tos(), &target);
+       status = cli_readlink(cli1, sname, talloc_tos(), &target, NULL, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
                goto out;
@@ -8041,7 +8212,6 @@ static bool run_acl_symlink_test(int dummy)
        char *posix_acl_sym = NULL;
        size_t posix_acl_len_sym = 0;
        struct security_descriptor *sd = NULL;
-       struct security_descriptor *sd_sym = NULL;
        TALLOC_CTX *frame = NULL;
 
        frame = talloc_stackframe();
@@ -8146,7 +8316,7 @@ static bool run_acl_symlink_test(int dummy)
                goto out;
        }
 
-       /* Open a handle on the symlink. */
+       /* Try a stat-open on the symlink, should also fail. */
        status = cli_ntcreate(cli,
                        sname,
                        0,
@@ -8159,23 +8329,8 @@ static bool run_acl_symlink_test(int dummy)
                        &fnum,
                        NULL);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               printf("cli_posix_open of %s failed (%s)\n",
-                       sname,
-                       nt_errstr(status));
-               goto out;
-       }
-
-       /* Get the Windows ACL on the symlink handle. Should fail */
-       status = cli_query_secdesc(cli,
-                               fnum,
-                               frame,
-                               &sd_sym);
-
-       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("cli_query_secdesc on a symlink gave %s. "
-                       "Should be NT_STATUS_ACCESS_DENIED.\n",
-                       nt_errstr(status));
+       if (NT_STATUS_IS_OK(status)) {
+               printf("Stat-open of symlink succeeded (should fail)\n");
                goto out;
        }
 
@@ -8193,19 +8348,6 @@ static bool run_acl_symlink_test(int dummy)
                goto out;
        }
 
-       /* Set the Windows ACL on the symlink handle. Should fail */
-       status = cli_set_security_descriptor(cli,
-                               fnum,
-                               SECINFO_DACL,
-                               sd);
-
-       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("cli_query_secdesc on a symlink gave %s. "
-                       "Should be NT_STATUS_ACCESS_DENIED.\n",
-                       nt_errstr(status));
-               goto out;
-       }
-
        /* Set the POSIX ACL on the symlink pathname. Should fail. */
        status = cli_posix_setacl(cli,
                                sname,
@@ -8886,6 +9028,11 @@ static bool run_posix_blocking_lock(int dummy)
                return false;
        }
 
+       status = torture_setup_unix_extensions(cli2);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
        cli_setatr(cli1, fname, 0, 0);
        cli_posix_unlink(cli1, fname);
 
@@ -9659,7 +9806,7 @@ static bool run_openattrtest(int dummy)
        return correct;
 }
 
-static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS list_fn(struct file_info *finfo,
                    const char *name, void *state)
 {
        int *matched = (int *)state;
@@ -9732,7 +9879,7 @@ static bool run_dirtest(int dummy)
        return correct;
 }
 
-static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
+static NTSTATUS del_fn(struct file_info *finfo, const char *mask,
                   void *state)
 {
        struct cli_state *pcli = (struct cli_state *)state;
@@ -9753,6 +9900,42 @@ static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mas
 }
 
 
+/*
+   send a raw ioctl - used by the torture code
+*/
+static NTSTATUS cli_raw_ioctl(struct cli_state *cli,
+                             uint16_t fnum,
+                             uint32_t code,
+                             DATA_BLOB *blob)
+{
+       uint16_t vwv[3];
+       NTSTATUS status;
+
+       PUSH_LE_U16(vwv + 0, 0, fnum);
+       PUSH_LE_U16(vwv + 1, 0, code >> 16);
+       PUSH_LE_U16(vwv + 2, 0, (code & 0xFFFF));
+
+       status = cli_smb(talloc_tos(),
+                        cli,
+                        SMBioctl,
+                        0,
+                        3,
+                        vwv,
+                        0,
+                        NULL,
+                        NULL,
+                        0,
+                        NULL,
+                        NULL,
+                        NULL,
+                        NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       *blob = data_blob_null;
+       return NT_STATUS_OK;
+}
+
 /*
   sees what IOCTLs are supported
  */
@@ -9809,7 +9992,7 @@ bool torture_ioctl_test(int dummy)
 
 
 /*
-  tries varients of chkpath
+  tries variants of chkpath
  */
 bool torture_chkpath_test(int dummy)
 {
@@ -9825,9 +10008,7 @@ bool torture_chkpath_test(int dummy)
        printf("starting chkpath test\n");
 
        /* cleanup from an old run */
-       cli_rmdir(cli, "\\chkpath.dir\\dir2");
-       cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
-       cli_rmdir(cli, "\\chkpath.dir");
+       torture_deltree(cli, "\\chkpath.dir");
 
        status = cli_mkdir(cli, "\\chkpath.dir");
        if (!NT_STATUS_IS_OK(status)) {
@@ -9888,9 +10069,7 @@ bool torture_chkpath_test(int dummy)
                ret = False;
        }
 
-       cli_rmdir(cli, "\\chkpath.dir\\dir2");
-       cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
-       cli_rmdir(cli, "\\chkpath.dir");
+       torture_deltree(cli, "\\chkpath.dir");
 
        if (!torture_close_connection(cli)) {
                return False;
@@ -9905,8 +10084,7 @@ static bool run_eatest(int dummy)
        const char *fname = "\\eatest.txt";
        bool correct = True;
        uint16_t fnum;
-       int i;
-       size_t num_eas;
+       size_t i, num_eas;
        struct ea_struct *ea_list = NULL;
        TALLOC_CTX *mem_ctx = talloc_init("eatest");
        NTSTATUS status;
@@ -9933,7 +10111,7 @@ static bool run_eatest(int dummy)
        for (i = 0; i < 10; i++) {
                fstring ea_name, ea_val;
 
-               slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
+               slprintf(ea_name, sizeof(ea_name), "EA_%zu", i);
                memset(ea_val, (char)i+1, i+1);
                status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
                if (!NT_STATUS_IS_OK(status)) {
@@ -9948,7 +10126,7 @@ static bool run_eatest(int dummy)
        for (i = 0; i < 10; i++) {
                fstring ea_name, ea_val;
 
-               slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
+               slprintf(ea_name, sizeof(ea_name), "EA_%zu", i+10);
                memset(ea_val, (char)i+1, i+1);
                status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
                if (!NT_STATUS_IS_OK(status)) {
@@ -9973,13 +10151,13 @@ static bool run_eatest(int dummy)
        }
 
        for (i = 0; i < num_eas; i++) {
-               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
                dump_data(0, ea_list[i].value.data,
                          ea_list[i].value.length);
        }
 
        /* Setting EA's to zero length deletes them. Test this */
-       printf("Now deleting all EA's - case indepenent....\n");
+       printf("Now deleting all EA's - case independent....\n");
 
 #if 1
        cli_set_ea_path(cli, fname, "", "", 0);
@@ -10005,7 +10183,7 @@ static bool run_eatest(int dummy)
 
        printf("num_eas = %d\n", (int)num_eas);
        for (i = 0; i < num_eas; i++) {
-               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               printf("%zu: ea_name = %s. Val = ", i, ea_list[i].name);
                dump_data(0, ea_list[i].value.data,
                          ea_list[i].value.length);
        }
@@ -10082,7 +10260,7 @@ static bool run_dirtest1(int dummy)
                correct = False;
 
        /* Ensure if we have the "must have" bits we only see the
-        * relevent entries.
+        * relevant entries.
         */
        num_seen = 0;
        cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
@@ -10606,10 +10784,9 @@ static void torture_createdels_done(struct tevent_req *subreq)
                subreq, struct tevent_req);
        struct torture_createdels_state *state = tevent_req_data(
                req, struct torture_createdels_state);
-       size_t num_parallel = talloc_array_length(state->reqs);
+       size_t i, num_parallel = talloc_array_length(state->reqs);
        NTSTATUS status;
        char *name;
-       int i;
 
        status = torture_createdel_recv(subreq);
        if (!NT_STATUS_IS_OK(status)){
@@ -10862,9 +11039,6 @@ static bool run_mangle1(int dummy)
        uint16_t fnum;
        fstring alt_name;
        NTSTATUS status;
-       time_t change_time, access_time, write_time;
-       off_t size;
-       uint32_t attr;
 
        printf("starting mangle1 test\n");
        if (!torture_open_connection(&cli, 0)) {
@@ -10898,8 +11072,7 @@ static bool run_mangle1(int dummy)
        }
        cli_close(cli, fnum);
 
-       status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
-                               &write_time, &size, &attr);
+       status = cli_qpathinfo1(cli, alt_name, NULL, NULL, NULL, NULL, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
                         nt_errstr(status));
@@ -10909,8 +11082,7 @@ static bool run_mangle1(int dummy)
        return true;
 }
 
-static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
-                                                struct file_info *f,
+static NTSTATUS mangle_illegal_list_shortname_fn(struct file_info *f,
                                                 const char *mask,
                                                 void *state)
 {
@@ -10927,8 +11099,7 @@ static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
        return NT_STATUS_OBJECT_NAME_INVALID;
 }
 
-static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
-                                           struct file_info *f,
+static NTSTATUS mangle_illegal_list_name_fn(struct file_info *f,
                                            const char *mask,
                                            void *state)
 {
@@ -11461,8 +11632,7 @@ static bool run_large_readx(int dummy)
        return correct;
 }
 
-static NTSTATUS msdfs_attribute_list_fn(const char *mnt,
-                                 struct file_info *finfo,
+static NTSTATUS msdfs_attribute_list_fn(struct file_info *finfo,
                                  const char *mask,
                                  void *private_data)
 {
@@ -11713,7 +11883,7 @@ static bool run_uid_regression_test(int dummy)
        int16_t old_vuid;
        int32_t old_cnum;
        bool correct = True;
-       struct smbXcli_tcon *orig_tcon = NULL;
+       struct smbXcli_tcon *tcon_copy = NULL;
        NTSTATUS status;
 
        printf("starting uid regression test\n");
@@ -11754,8 +11924,20 @@ static bool run_uid_regression_test(int dummy)
        }
 
        old_cnum = cli_state_get_tid(cli);
-       orig_tcon = cli_state_save_tcon(cli);
-       if (orig_tcon == NULL) {
+       /*
+        * This is an SMB1-only test.
+        * Copy the tcon, not "save/restore".
+        *
+        * In SMB1 the cli_tdis() below frees
+        * cli->smb1.tcon so we need a copy
+        * of the struct to put back for the
+        * second tdis call with invalid vuid.
+        *
+        * This is a test-only hack. Real client code
+        * uses cli_state_save_tcon_share()/cli_state_restore_tcon_share().
+        */
+       tcon_copy = smbXcli_tcon_copy(cli, cli->smb1.tcon);
+       if (tcon_copy == NULL) {
                correct = false;
                goto out;
        }
@@ -11771,11 +11953,11 @@ static bool run_uid_regression_test(int dummy)
        } else {
                d_printf("First tdis failed (%s)\n", nt_errstr(status));
                correct = false;
-               cli_state_restore_tcon(cli, orig_tcon);
+               cli->smb1.tcon = tcon_copy;
                goto out;
        }
 
-       cli_state_restore_tcon(cli, orig_tcon);
+       cli->smb1.tcon = tcon_copy;
        cli_state_set_uid(cli, old_vuid);
        cli_state_set_tid(cli, old_cnum);
 
@@ -11806,7 +11988,7 @@ static bool run_uid_regression_test(int dummy)
 static const char *illegal_chars = "*\\/?<>|\":";
 static char force_shortname_chars[] = " +,.[];=\177";
 
-static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS shortname_del_fn(struct file_info *finfo,
                             const char *mask, void *state)
 {
        struct cli_state *pcli = (struct cli_state *)state;
@@ -11838,7 +12020,7 @@ struct sn_state {
        bool val;
 };
 
-static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
+static NTSTATUS shortname_list_fn(struct file_info *finfo,
                              const char *name, void *state)
 {
        struct sn_state *s = (struct sn_state  *)state;
@@ -12351,8 +12533,7 @@ static bool run_streamerror(int dummy)
                return false;
        }
 
-       cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
-       cli_rmdir(cli, dname);
+       torture_deltree(cli, dname);
 
        status = cli_mkdir(cli, dname);
        if (!NT_STATUS_IS_OK(status)) {
@@ -12645,59 +12826,397 @@ static bool run_symlink_open_test(int dummy)
        return correct;
 }
 
-/*
- * Only testing minimal time strings, as the others
- * need (locale-dependent) guessing at what strftime does and
- * even may differ in builds.
- */
-static bool timesubst_test(void)
+static NTSTATUS smb1_wild_mangle_list_fn(struct file_info *finfo,
+                                       const char *name,
+                                       void *state)
 {
-       TALLOC_CTX *ctx = NULL;
-       /* Sa 23. Dez 04:33:20 CET 2017 */
-       const struct timeval tv = { 1514000000, 123 };
-       const char* expect_minimal = "20171223_033320";
-       const char* expect_minus   = "20171223_033320_000123";
-       char *s;
-       char *env_tz, *orig_tz = NULL;
-       bool result = true;
-
-       ctx = talloc_new(NULL);
+       char **mangled_name_return = (char **)state;
+       bool is_mangled = strchr(finfo->name, '~');
 
-       env_tz = getenv("TZ");
-       if(env_tz) {
-               orig_tz = talloc_strdup(ctx, env_tz);
+       if (is_mangled) {
+               *mangled_name_return = talloc_strdup(NULL, finfo->name);
+               if (*mangled_name_return == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
        }
-       setenv("TZ", "UTC", 1);
+       return NT_STATUS_OK;
+}
 
-       s = minimal_timeval_string(ctx, &tv, false);
+static bool run_smb1_wild_mangle_unlink_test(int dummy)
+{
+       static struct cli_state *cli_posix = NULL;
+       static struct cli_state *cli = NULL;
+       uint16_t fnum = (uint16_t)-1;
+       bool correct = false;
+       const char *dname = "smb1_wild_mangle_unlink";
+       const char *aname = "smb1_wild_mangle_unlink/a";
+       const char *star_name = "smb1_wild_mangle_unlink/*";
+       char *windows_unlink_name = NULL;
+       char *mangled_name = NULL;
+       NTSTATUS status;
 
-       if(!s || strcmp(s, expect_minimal)) {
-               printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
-                      "[%s]\n", s ? s : "<nil>", expect_minimal);
-               result = false;
+       printf("Starting SMB1 wild mangle unlink test\n");
+
+       /* Open a Windows connection. */
+       if (!torture_open_connection(&cli, 0)) {
+               return false;
        }
-       TALLOC_FREE(s);
-       s = minimal_timeval_string(ctx, &tv, true);
-       if(!s || strcmp(s, expect_minus)) {
-               printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
-                      "[%s]\n", s ? s : "<nil>", expect_minus);
-               result = false;
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       /* Open a POSIX connection. */
+       if (!torture_open_connection(&cli_posix, 0)) {
+               goto out;
        }
-       TALLOC_FREE(s);
 
-       if(orig_tz) {
-               setenv("TZ", orig_tz, 1);
+       smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
+
+       status = torture_setup_unix_extensions(cli_posix);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("server doesn't support POSIX\n");
+               goto out;
        }
 
-       TALLOC_FREE(ctx);
-       return result;
-}
+       /* Start fresh. */
+       torture_deltree(cli, dname);
 
-static bool run_local_substitute(int dummy)
-{
-       bool ok = true;
+       /*
+        * Create two files - 'a' and '*'.
+        * We need POSIX extensions for this as '*'
+        * is not a valid Windows name.
+        */
 
-       ok &= subst_test("%U", "bla", "", -1, -1, "bla");
+       status = cli_mkdir(cli, dname);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_mkdir of %s returned %s\n",
+                       dname,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       status = cli_posix_open(cli_posix,
+                               aname,
+                               O_RDWR|O_CREAT|O_EXCL,
+                               0660,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open (create) of %s returned %s\n",
+                       aname,
+                       nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = cli_posix_open(cli_posix,
+                               star_name,
+                               O_RDWR|O_CREAT|O_EXCL,
+                               0660,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open (create) of %s returned %s\n",
+                       star_name,
+                       nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       status = cli_list(cli,
+                       star_name,
+                       0,
+                       smb1_wild_mangle_list_fn,
+                       &mangled_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_list of %s returned %s\n",
+                       star_name,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       if (mangled_name == NULL) {
+               goto out;
+       }
+
+       printf("mangled_name = %s\n",
+               mangled_name);
+
+       /*
+        * Try a Windows unlink with the mangled name.
+        * This should *NOT* unlink the 'a' name.
+        */
+
+       windows_unlink_name = talloc_asprintf(cli_posix,
+                                       "%s\\%s",
+                                       dname,
+                                       mangled_name);
+
+       status = cli_unlink(cli, windows_unlink_name, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_unlink of %s returned %s\n",
+                       windows_unlink_name,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       /* Does 'a' still exist ? */
+       status = cli_posix_open(cli_posix,
+                               aname,
+                               O_RDONLY,
+                               0,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open O_RNONLY of %s returned %s\n",
+                       aname,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       correct = true;
+
+  out:
+
+       TALLOC_FREE(windows_unlink_name);
+       TALLOC_FREE(mangled_name);
+
+       if (cli != NULL) {
+               torture_deltree(cli, dname);
+               torture_close_connection(cli);
+       }
+
+       if (cli_posix != NULL) {
+               torture_close_connection(cli_posix);
+       }
+
+       return correct;
+}
+
+static bool run_smb1_wild_mangle_rename_test(int dummy)
+{
+       static struct cli_state *cli_posix = NULL;
+       static struct cli_state *cli = NULL;
+       uint16_t fnum = (uint16_t)-1;
+       bool correct = false;
+       const char *dname = "smb1_wild_mangle_rename";
+       const char *fooname = "smb1_wild_mangle_rename/foo";
+       const char *foostar_name = "smb1_wild_mangle_rename/fo*";
+       const char *wild_name = "smb1_wild_mangle_rename/*";
+       char *windows_rename_src = NULL;
+       const char *windows_rename_dst = "smb1_wild_mangle_rename\\bar";
+       char *mangled_name = NULL;
+       NTSTATUS status;
+
+       printf("Starting SMB1 wild mangle rename test\n");
+
+       if (!torture_open_connection(&cli_posix, 0)) {
+               return false;
+       }
+
+       smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
+
+       status = torture_setup_unix_extensions(cli_posix);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("server doesn't support POSIX\n");
+               return false;
+       }
+
+       /* Open a Windows connection. */
+       if (!torture_open_connection(&cli, 0)) {
+               goto out;
+       }
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       /* Ensure we start from fresh. */
+       torture_deltree(cli, dname);
+
+       /*
+        * Create two files - 'foo' and 'fo*'.
+        * We need POSIX extensions for this as 'fo*'
+        * is not a valid Windows name.
+        */
+
+       status = cli_posix_mkdir(cli_posix, dname, 0770);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_mkdir of %s returned %s\n",
+                       dname,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       status = cli_posix_open(cli_posix,
+                               fooname,
+                               O_RDWR|O_CREAT|O_EXCL,
+                               0660,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open (create) of %s returned %s\n",
+                       fooname,
+                       nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = cli_posix_open(cli_posix,
+                               foostar_name,
+                               O_RDWR|O_CREAT|O_EXCL,
+                               0660,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open (create) of %s returned %s\n",
+                       foostar_name,
+                       nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       /*
+        * Get the mangled name. We can re-use the
+        * previous smb1_wild_mangle_list_fn for this.
+        */
+
+       status = cli_list(cli,
+                       wild_name,
+                       0,
+                       smb1_wild_mangle_list_fn,
+                       &mangled_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_list of %s returned %s\n",
+                       wild_name,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       if (mangled_name == NULL) {
+               goto out;
+       }
+
+       printf("mangled_name = %s\n",
+               mangled_name);
+
+       /*
+        * Try a Windows rename with the mangled name.
+        * This should *NOT* rename the 'foo' name.
+        */
+
+       windows_rename_src = talloc_asprintf(cli_posix,
+                                       "%s\\%s",
+                                       dname,
+                                       mangled_name);
+
+       status = cli_rename(cli,
+                       windows_rename_src,
+                       windows_rename_dst,
+                       false);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_rename of %s -> %s returned %s\n",
+                       windows_rename_src,
+                       windows_rename_dst,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       /* Does 'foo' still exist ? */
+       status = cli_posix_open(cli_posix,
+                               fooname,
+                               O_RDONLY,
+                               0,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open O_RNONLY of %s returned %s\n",
+                       fooname,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+
+       correct = true;
+
+  out:
+
+       TALLOC_FREE(mangled_name);
+       TALLOC_FREE(windows_rename_src);
+
+       if (cli != NULL) {
+               torture_deltree(cli, dname);
+               torture_close_connection(cli);
+       }
+
+       torture_close_connection(cli_posix);
+
+       return correct;
+}
+
+/*
+ * Only testing minimal time strings, as the others
+ * need (locale-dependent) guessing at what strftime does and
+ * even may differ in builds.
+ */
+static bool timesubst_test(void)
+{
+       TALLOC_CTX *ctx = NULL;
+       /* Sa 23. Dez 04:33:20 CET 2017 */
+       const struct timeval tv = { 1514000000, 123 };
+       const char* expect_minimal = "20171223_033320";
+       const char* expect_minus   = "20171223_033320_000123";
+       char *s;
+       char *env_tz, *orig_tz = NULL;
+       bool result = true;
+
+       ctx = talloc_new(NULL);
+
+       env_tz = getenv("TZ");
+       if(env_tz) {
+               orig_tz = talloc_strdup(ctx, env_tz);
+       }
+       setenv("TZ", "UTC", 1);
+
+       s = minimal_timeval_string(ctx, &tv, false);
+
+       if(!s || strcmp(s, expect_minimal)) {
+               printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
+                      "[%s]\n", s ? s : "<nil>", expect_minimal);
+               result = false;
+       }
+       TALLOC_FREE(s);
+       s = minimal_timeval_string(ctx, &tv, true);
+       if(!s || strcmp(s, expect_minus)) {
+               printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
+                      "[%s]\n", s ? s : "<nil>", expect_minus);
+               result = false;
+       }
+       TALLOC_FREE(s);
+
+       if(orig_tz) {
+               setenv("TZ", orig_tz, 1);
+       }
+
+       TALLOC_FREE(ctx);
+       return result;
+}
+
+static bool run_local_substitute(int dummy)
+{
+       bool ok = true;
+
+       ok &= subst_test("%U", "bla", "", -1, -1, "bla");
        ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
        ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
        ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
@@ -13953,7 +14472,7 @@ static bool run_local_hex_encode_buf(int dummy)
 {
        char buf[17];
        uint8_t src[8];
-       int i;
+       size_t i;
 
        for (i=0; i<sizeof(src); i++) {
                src[i] = i;
@@ -14019,7 +14538,7 @@ static const char *remove_duplicate_addrs2_test_strings_result[] = {
 
 static bool run_local_remove_duplicate_addrs2(int dummy)
 {
-       struct ip_service test_vector[28];
+       struct samba_sockaddr test_vector[28];
        size_t count, i;
 
        /* Construct the sockaddr_storage test vector. */
@@ -14040,7 +14559,7 @@ static bool run_local_remove_duplicate_addrs2(int dummy)
                        return false;
                }
                memset(&test_vector[i], '\0', sizeof(test_vector[i]));
-               memcpy(&test_vector[i].ss,
+               memcpy(&test_vector[i].u.ss,
                        res->ai_addr,
                        res->ai_addrlen);
                freeaddrinfo(res);
@@ -14057,7 +14576,7 @@ static bool run_local_remove_duplicate_addrs2(int dummy)
        for (i = 0; i < count; i++) {
                char addr[INET6_ADDRSTRLEN];
 
-               print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
+               print_sockaddr(addr, sizeof(addr), &test_vector[i].u.ss);
 
                if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
                        fprintf(stderr, "mismatch on [%zu] [%s] [%s]\n",
@@ -14206,38 +14725,427 @@ static bool run_local_canonicalize_path(int dummy)
        }
        return true;
 }
+struct session_setup_nt1_truncated_state {
+       uint16_t vwv[13];
+       uint8_t bytes[20];
+};
 
-static bool run_ign_bad_negprot(int dummy)
-{
-       struct tevent_context *ev;
-       struct tevent_req *req;
-       struct smbXcli_conn *conn;
-       struct sockaddr_storage ss;
-       NTSTATUS status;
-       int fd;
-       bool ok;
+static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
 
-       printf("starting ignore bad negprot\n");
+static struct tevent_req *smb1_session_setup_nt1_truncated_send(
+               TALLOC_CTX *mem_ctx,
+               struct tevent_context *ev,
+               struct smbXcli_conn *conn)
+{
+       uint16_t *vwv = NULL;
+       uint8_t *bytes = NULL;
+       const char *pass = "12345678";
+       const char *uname = "z";
+       struct session_setup_nt1_truncated_state *state = NULL;
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
 
-       ok = resolve_name(host, &ss, 0x20, true);
-       if (!ok) {
-               d_fprintf(stderr, "Could not resolve name %s\n", host);
-               return false;
+       req = tevent_req_create(mem_ctx,
+                               &state,
+                               struct session_setup_nt1_truncated_state);
+       if (req == NULL) {
+               return NULL;
        }
-
-       status = open_socket_out(&ss, 445, 10000, &fd);
-       if (!NT_STATUS_IS_OK(status)) {
-               d_fprintf(stderr, "open_socket_out failed: %s\n",
-                         nt_errstr(status));
-               return false;
+       vwv = &state->vwv[0];
+       bytes = &state->bytes[0];
+
+       SCVAL(vwv+0,  0, 0xff);
+       SCVAL(vwv+0,  1, 0);
+       SSVAL(vwv+1,  0, 0);
+       SSVAL(vwv+2,  0, 8192);
+       SSVAL(vwv+3,  0, 2);
+       SSVAL(vwv+4,  0, 1);
+       SIVAL(vwv+5,  0, 0);
+       SSVAL(vwv+7,  0, strlen(pass)); /* OEMPasswordLen */
+       SSVAL(vwv+8,  0, 0); /* UnicodePasswordLen */
+       SSVAL(vwv+9,  0, 0); /* reserved */
+       SSVAL(vwv+10, 0, 0); /* reserved */
+       SIVAL(vwv+11, 0, CAP_STATUS32);
+
+       memcpy(bytes, pass, strlen(pass));
+       bytes += strlen(pass);
+       memcpy(bytes, uname, strlen(uname)+1);
+
+       subreq = smb1cli_req_send(state, ev, conn,
+                                 SMBsesssetupX,
+                                 0, /*  additional_flags */
+                                 0, /*  clear_flags */
+                                 0, /*  additional_flags2 */
+                                 0, /*  clear_flags2 */
+                                 10000, /* timeout_msec */
+                                 getpid(),
+                                 NULL, /* tcon */
+                                 NULL, /* session */
+                                 13, /* wct */
+                                 state->vwv,
+                                 strlen(pass), /* Truncate length at password. */
+                                 state->bytes);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
        }
+       tevent_req_set_callback(subreq,
+                               smb1_session_setup_nt1_truncated_done,
+                               req);
+       return req;
+}
 
-       conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
-                                  NULL, 0);
-       if (conn == NULL) {
-               d_fprintf(stderr, "smbXcli_conn_create failed\n");
-               return false;
-       }
+static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct session_setup_nt1_truncated_state *state =
+               tevent_req_data(req,
+               struct session_setup_nt1_truncated_state);
+       NTSTATUS status;
+       struct smb1cli_req_expected_response expected[] = {
+       {
+               .status = NT_STATUS_OK,
+               .wct    = 3,
+       },
+       };
+
+       status = smb1cli_req_recv(subreq, state,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 NULL, /* pvwv_offset */
+                                 NULL,
+                                 NULL,
+                                 NULL, /* pbytes_offset */
+                                 NULL,
+                                 expected, ARRAY_SIZE(expected));
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+static bool run_smb1_truncated_sesssetup(int dummy)
+{
+       struct tevent_context *ev;
+       struct tevent_req *req;
+       struct smbXcli_conn *conn;
+       struct sockaddr_storage ss;
+       NTSTATUS status;
+       int fd;
+       bool ok;
+
+       printf("Starting send truncated SMB1 sesssetup.\n");
+
+       ok = resolve_name(host, &ss, 0x20, true);
+       if (!ok) {
+               d_fprintf(stderr, "Could not resolve name %s\n", host);
+               return false;
+       }
+
+       status = open_socket_out(&ss, 445, 10000, &fd);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "open_socket_out failed: %s\n",
+                         nt_errstr(status));
+               return false;
+       }
+
+       conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
+                                  NULL, 0, NULL);
+       if (conn == NULL) {
+               d_fprintf(stderr, "smbXcli_conn_create failed\n");
+               return false;
+       }
+
+       status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "smbXcli_negprot failed!\n");
+               return false;
+       }
+
+       ev = samba_tevent_context_init(talloc_tos());
+       if (ev == NULL) {
+               d_fprintf(stderr, "samba_tevent_context_init failed\n");
+               return false;
+       }
+
+       req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
+       if (req == NULL) {
+               d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
+               return false;
+       }
+
+       ok = tevent_req_poll_ntstatus(req, ev, &status);
+       if (!ok) {
+               d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
+                       nt_errstr(status));
+               return false;
+       }
+
+       status = smb1_session_setup_nt1_truncated_recv(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
+                         "%s, expected NT_STATUS_OK\n",
+                         nt_errstr(status));
+               return false;
+       }
+
+       TALLOC_FREE(conn);
+       return true;
+}
+
+struct smb1_negotiate_exit_state {
+       int dummy;
+};
+
+static void smb1_negotiate_exit_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb1_negotiate_exit_send(
+               TALLOC_CTX *mem_ctx,
+               struct tevent_context *ev,
+               struct smbXcli_conn *conn)
+{
+       struct smb1_negotiate_exit_state *state = NULL;
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
+
+       req = tevent_req_create(mem_ctx,
+                               &state,
+                               struct smb1_negotiate_exit_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       subreq = smb1cli_req_send(state, ev, conn,
+                                 SMBexit,
+                                 0, /*  additional_flags */
+                                 0, /*  clear_flags */
+                                 0, /*  additional_flags2 */
+                                 0, /*  clear_flags2 */
+                                 10000, /* timeout_msec */
+                                 getpid(),
+                                 NULL, /* tcon */
+                                 NULL, /* session */
+                                 0, /* wct */
+                                 NULL,
+                                 0,
+                                 NULL);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq,
+                               smb1_negotiate_exit_done,
+                               req);
+       return req;
+}
+
+static void smb1_negotiate_exit_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct smb1_negotiate_exit_state *state =
+               tevent_req_data(req,
+               struct smb1_negotiate_exit_state);
+       NTSTATUS status;
+       struct smb1cli_req_expected_response expected[] = {
+       {
+               .status = NT_STATUS_OK,
+               .wct    = 0,
+       },
+       };
+
+       status = smb1cli_req_recv(subreq, state,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 NULL, /* pvwv_offset */
+                                 NULL,
+                                 NULL,
+                                 NULL, /* pbytes_offset */
+                                 NULL,
+                                 expected, ARRAY_SIZE(expected));
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+static bool do_smb1_exit(TALLOC_CTX *mem_ctx,
+                        struct tevent_context *ev,
+                        struct smbXcli_conn *conn)
+{
+       struct tevent_req *req;
+       bool ok;
+       NTSTATUS status;
+       NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);;
+
+       req = smb1_negotiate_exit_send(ev, ev, conn);
+       if (req == NULL) {
+               d_fprintf(stderr, "smb1_negotiate_exit_send failed\n");
+               return false;
+       }
+
+       ok = tevent_req_poll_ntstatus(req, ev, &status);
+       if (!ok) {
+               d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
+                       nt_errstr(status));
+               return false;
+       }
+
+       status = smb1_negotiate_exit_recv(req);
+       if (!NT_STATUS_EQUAL(status, expected_status)) {
+               d_fprintf(stderr, "smb1_negotiate_exit_recv returned "
+                         "%s, expected ERRSRV, ERRinvnid\n",
+                         nt_errstr(status));
+               return false;
+       }
+       return true;
+}
+
+static bool run_smb1_negotiate_exit(int dummy)
+{
+       struct tevent_context *ev;
+       struct smbXcli_conn *conn;
+       struct sockaddr_storage ss;
+       NTSTATUS status;
+       int fd;
+       bool ok;
+
+       printf("Starting send SMB1 negotiate+exit.\n");
+
+       ok = resolve_name(host, &ss, 0x20, true);
+       if (!ok) {
+               d_fprintf(stderr, "Could not resolve name %s\n", host);
+               return false;
+       }
+
+       status = open_socket_out(&ss, 445, 10000, &fd);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "open_socket_out failed: %s\n",
+                         nt_errstr(status));
+               return false;
+       }
+
+       conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
+                                  NULL, 0, NULL);
+       if (conn == NULL) {
+               d_fprintf(stderr, "smbXcli_conn_create failed\n");
+               return false;
+       }
+
+       status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "smbXcli_negprot failed!\n");
+               return false;
+       }
+
+       ev = samba_tevent_context_init(talloc_tos());
+       if (ev == NULL) {
+               d_fprintf(stderr, "samba_tevent_context_init failed\n");
+               return false;
+       }
+
+       /*
+        * Call do_smb1_exit twice to catch a server crash, the
+        * server sends the first return code then crashes.
+        */
+       ok = do_smb1_exit(ev, ev, conn);
+       if (!ok) {
+               d_fprintf(stderr, "do_smb1_exit (1) failed\n");
+               return false;
+       }
+       ok = do_smb1_exit(ev, ev, conn);
+       if (!ok) {
+               d_fprintf(stderr, "do_smb1_exit (2) failed\n");
+               return false;
+       }
+
+       TALLOC_FREE(conn);
+       return true;
+}
+
+static bool run_smb1_negotiate_tcon(int dummy)
+{
+       struct cli_state *cli = NULL;
+       uint16_t cnum = 0;
+       uint16_t max_xmit = 0;
+       NTSTATUS status;
+
+       printf("Starting send SMB1 negotiate+tcon.\n");
+       cli = open_nbt_connection();
+       if (cli == NULL) {
+               d_fprintf(stderr, "open_nbt_connection failed!\n");
+               return false;
+       }
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       status = smbXcli_negprot(cli->conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "smbXcli_negprot failed %s!\n",
+                       nt_errstr(status));
+               return false;
+       }
+        status = cli_raw_tcon(cli,
+                             share,
+                             "",
+                             "?????",
+                             &max_xmit,
+                             &cnum);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               d_fprintf(stderr, "cli_raw_tcon failed - got %s "
+                       "(should get NT_STATUS_ACCESS_DENIED)!\n",
+                       nt_errstr(status));
+               return false;
+       }
+       return true;
+}
+
+static bool run_ign_bad_negprot(int dummy)
+{
+       struct tevent_context *ev;
+       struct tevent_req *req;
+       struct smbXcli_conn *conn;
+       struct sockaddr_storage ss;
+       NTSTATUS status;
+       int fd;
+       bool ok;
+
+       printf("starting ignore bad negprot\n");
+
+       ok = resolve_name(host, &ss, 0x20, true);
+       if (!ok) {
+               d_fprintf(stderr, "Could not resolve name %s\n", host);
+               return false;
+       }
+
+       status = open_socket_out(&ss, 445, 10000, &fd);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "open_socket_out failed: %s\n",
+                         nt_errstr(status));
+               return false;
+       }
+
+       conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
+                                  NULL, 0, NULL);
+       if (conn == NULL) {
+               d_fprintf(stderr, "smbXcli_conn_create failed\n");
+               return false;
+       }
 
        status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
        if (NT_STATUS_IS_OK(status)) {
@@ -14282,6 +15190,7 @@ static bool run_ign_bad_negprot(int dummy)
        return true;
 }
 
+
 static double create_procs(bool (*fn)(int), bool *result)
 {
        int i, status;
@@ -14592,10 +15501,58 @@ static struct {
                .name  = "POSIX-ACL-SHAREROOT",
                .fn    = run_posix_acl_shareroot_test,
        },
+       {
+               .name  = "POSIX-LS-WILDCARD",
+               .fn    = run_posix_ls_wildcard_test,
+       },
+       {
+               .name  = "POSIX-LS-SINGLE",
+               .fn    = run_posix_ls_single_test,
+       },
+       {
+               .name  = "POSIX-READLINK",
+               .fn    = run_posix_readlink_test,
+       },
+       {
+               .name  = "POSIX-STAT",
+               .fn    = run_posix_stat_test,
+       },
+       {
+               .name  = "POSIX-SYMLINK-PARENT",
+               .fn    = run_posix_symlink_parent_test,
+       },
+       {
+               .name  = "POSIX-SYMLINK-CHMOD",
+               .fn    = run_posix_symlink_chmod_test,
+       },
+       {
+               .name  = "POSIX-SYMLINK-RENAME",
+               .fn    = run_posix_symlink_rename_test,
+       },
+       {
+               .name  = "POSIX-DIR-DEFAULT-ACL",
+               .fn    = run_posix_dir_default_acl_test,
+       },
+       {
+               .name  = "POSIX-SYMLINK-GETPATHINFO",
+               .fn    = run_posix_symlink_getpathinfo_test,
+       },
+       {
+               .name  = "POSIX-SYMLINK-SETPATHINFO",
+               .fn    = run_posix_symlink_setpathinfo_test,
+       },
        {
                .name  = "WINDOWS-BAD-SYMLINK",
                .fn    = run_symlink_open_test,
        },
+       {
+               .name  = "SMB1-WILD-MANGLE-UNLINK",
+               .fn    = run_smb1_wild_mangle_unlink_test,
+       },
+       {
+               .name  = "SMB1-WILD-MANGLE-RENAME",
+               .fn    = run_smb1_wild_mangle_rename_test,
+       },
        {
                .name  = "CASE-INSENSITIVE-CREATE",
                .fn    = run_case_insensitive_create,
@@ -14650,10 +15607,6 @@ static struct {
                .name  = "DELETE-PRINT",
                .fn    = run_delete_print_test,
        },
-       {
-               .name  = "WILDDELETE",
-               .fn    = run_wild_deletetest,
-       },
        {
                .name  = "DELETE-LN",
                .fn    = run_deletetest_ln,
@@ -14854,6 +15807,70 @@ static struct {
                .name  = "SMB2-QUOTA1",
                .fn    = run_smb2_quota1,
        },
+       {
+               .name  = "SMB2-STREAM-ACL",
+               .fn    = run_smb2_stream_acl,
+       },
+       {
+               .name  = "SMB2-LIST-DIR-ASYNC",
+               .fn    = run_list_dir_async_test,
+       },
+       {
+               .name  = "SMB2-DEL-ON-CLOSE-NONEMPTY",
+               .fn    = run_delete_on_close_non_empty,
+       },
+       {
+               .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-YES",
+               .fn    = run_delete_on_close_nonwrite_delete_yes_test,
+       },
+       {
+               .name  = "SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO",
+               .fn    = run_delete_on_close_nonwrite_delete_no_test,
+       },
+       {
+               .name  = "SMB2-DFS-PATHS",
+               .fn    = run_smb2_dfs_paths,
+       },
+       {
+               .name  = "SMB2-NON-DFS-SHARE",
+               .fn    = run_smb2_non_dfs_share,
+       },
+       {
+               .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
+               .fn    = run_smb2_dfs_share_non_dfs_path,
+       },
+       {
+               .name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+               .fn    = run_smb2_dfs_filename_leading_backslash,
+       },
+       {
+               .name  = "SMB1-TRUNCATED-SESSSETUP",
+               .fn    = run_smb1_truncated_sesssetup,
+       },
+       {
+               .name  = "SMB1-NEGOTIATE-EXIT",
+               .fn    = run_smb1_negotiate_exit,
+       },
+       {
+               .name  = "SMB1-NEGOTIATE-TCON",
+               .fn    = run_smb1_negotiate_tcon,
+       },
+       {
+               .name  = "SMB1-DFS-PATHS",
+               .fn    = run_smb1_dfs_paths,
+       },
+       {
+               .name  = "SMB1-DFS-SEARCH-PATHS",
+               .fn    = run_smb1_dfs_search_paths,
+       },
+       {
+               .name  = "SMB1-DFS-OPERATIONS",
+               .fn    = run_smb1_dfs_operations,
+       },
+       {
+               .name  = "SMB1-DFS-BADPATH",
+               .fn    = run_smb1_dfs_check_badpath,
+       },
        {
                .name  = "CLEANUP1",
                .fn    = run_cleanup1,
@@ -14954,6 +15971,14 @@ static struct {
                .name  = "LOCAL-STREAM-NAME",
                .fn    = run_local_stream_name,
        },
+       {
+               .name  = "LOCAL-STR-MATCH-MSWILD",
+               .fn    = run_str_match_mswild,
+       },
+       {
+               .name  = "LOCAL-STR-MATCH-REGEX-SUB1",
+               .fn    = run_str_match_regex_sub1,
+       },
        {
                .name  = "WBCLIENT-MULTI-PING",
                .fn    = run_wbclient_multi_ping,
@@ -15078,6 +16103,10 @@ static struct {
                .name  = "hide-new-files-timeout",
                .fn    = run_hidenewfiles,
        },
+       {
+               .name  = "hide-new-files-timeout-showdirs",
+               .fn    = run_hidenewfiles_showdirs,
+       },
 #ifdef CLUSTER_SUPPORT
        {
                .name  = "ctdbd-conn1",
@@ -15088,6 +16117,14 @@ static struct {
                .name  = "readdir-timestamp",
                .fn    = run_readdir_timestamp,
        },
+       {
+               .name  = "rpc-scale",
+               .fn    = run_rpc_scale,
+       },
+       {
+               .name  = "LOCAL-TDB-VALIDATE",
+               .fn    = run_tdb_validate,
+       },
        {
                .name = NULL,
        },