torture3: Add test for smbd crash
[samba.git] / source3 / torture / torture.c
index 09e8b93abee28dfd0ae007dcc526c20c06972ef4..2c10ae87e8e3e4a8735dd2bec94e8f5bd4c9538e 100644 (file)
@@ -108,15 +108,7 @@ static bool force_cli_encryption(struct cli_state *c,
                return false;
        }
 
-       if (c->use_kerberos) {
-               status = cli_gss_smb_encryption_start(c);
-       } else {
-               status = cli_raw_ntlm_smb_encryption_start(c,
-                                               username,
-                                               password,
-                                               workgroup);
-       }
-
+       status = cli_smb1_setup_encryption(c, torture_creds);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Encryption required and "
                        "setup failed with error %s.\n",
@@ -1341,7 +1333,7 @@ static bool run_tcon_test(int dummy)
                return False;
        }
 
-       status = cli_tree_connect(cli, share, "?????", password);
+       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));
@@ -1466,7 +1458,7 @@ static bool tcon_devtest(struct cli_state *cli,
        NTSTATUS status;
        bool ret;
 
-       status = cli_tree_connect(cli, myshare, devtype, password);
+       status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
 
        if (NT_STATUS_IS_OK(expected_error)) {
                if (NT_STATUS_IS_OK(status)) {
@@ -5057,34 +5049,419 @@ static bool run_rename_access(int dummy)
                        src, dst, nt_errstr(status));
                goto fail;
        }
-       status = cli_rename(cli, dsrc, ddst);
-       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("rename of %s -> %s should be ACCESS denied, was %s\n",
-                       src, dst, nt_errstr(status));
+       status = cli_rename(cli, dsrc, ddst);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("rename of %s -> %s should be ACCESS denied, was %s\n",
+                       src, dst, nt_errstr(status));
+               goto fail;
+       }
+
+       TALLOC_FREE(frame);
+       return true;
+
+  fail:
+
+       if (posix_cli) {
+               torture_close_connection(posix_cli);
+       }
+
+       if (cli) {
+               if (fnum != (uint64_t)-1) {
+                       cli_close(cli, fnum);
+               }
+               cli_unlink(cli, src,
+                       FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+               cli_unlink(cli, dst,
+                       FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+               cli_rmdir(cli, dsrc);
+               cli_rmdir(cli, ddst);
+               cli_rmdir(cli, dname);
+
+               torture_close_connection(cli);
+       }
+
+       TALLOC_FREE(frame);
+       return false;
+}
+
+/*
+  Test owner rights ACE.
+ */
+static bool run_owner_rights(int dummy)
+{
+       static struct cli_state *cli = NULL;
+       const char *fname = "owner_rights.txt";
+       uint16_t fnum = (uint16_t)-1;
+       struct security_descriptor *sd = NULL;
+       struct security_descriptor *newsd = NULL;
+       NTSTATUS status;
+       TALLOC_CTX *frame = NULL;
+
+       frame = talloc_stackframe();
+       printf("starting owner rights test\n");
+
+       /* Windows connection. */
+       if (!torture_open_connection(&cli, 0)) {
+               goto fail;
+       }
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       /* Start with a clean slate. */
+       cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+
+       /* Create the test file. */
+       /* Now try and open for read and write-dac. */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               GENERIC_ALL_ACCESS,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_CREATE,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Create of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Get the original SD. */
+       status = cli_query_secdesc(cli,
+                               fnum,
+                               frame,
+                               &sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_query_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /*
+        * Add an "owner-rights" ACE denying WRITE_DATA,
+        * and an "owner-rights" ACE allowing READ_DATA.
+        */
+
+       newsd = security_descriptor_dacl_create(frame,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       SID_OWNER_RIGHTS,
+                                       SEC_ACE_TYPE_ACCESS_DENIED,
+                                       FILE_WRITE_DATA,
+                                       0,
+                                       SID_OWNER_RIGHTS,
+                                       SEC_ACE_TYPE_ACCESS_ALLOWED,
+                                       FILE_READ_DATA,
+                                       0,
+                                       NULL);
+       if (newsd == NULL) {
+               goto fail;
+       }
+       sd->dacl = security_acl_concatenate(frame,
+                                       newsd->dacl,
+                                       sd->dacl);
+       if (sd->dacl == NULL) {
+               goto fail;
+       }
+       status = cli_set_secdesc(cli, fnum, sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_set_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       fnum = (uint16_t)-1;
+
+       /* Try and open for FILE_WRITE_DATA */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               FILE_WRITE_DATA,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_OPEN,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("Open of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Now try and open for FILE_READ_DATA */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               FILE_READ_DATA,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_OPEN,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Restore clean slate. */
+       TALLOC_FREE(sd);
+       cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+
+       /* Create the test file. */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               GENERIC_ALL_ACCESS,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_CREATE,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Create of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Get the original SD. */
+       status = cli_query_secdesc(cli,
+                               fnum,
+                               frame,
+                               &sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_query_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /*
+        * Add an "owner-rights ACE denying WRITE_DATA,
+        * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
+        */
+
+       newsd = security_descriptor_dacl_create(frame,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       SID_OWNER_RIGHTS,
+                                       SEC_ACE_TYPE_ACCESS_DENIED,
+                                       FILE_WRITE_DATA,
+                                       0,
+                                       SID_OWNER_RIGHTS,
+                                       SEC_ACE_TYPE_ACCESS_ALLOWED,
+                                       FILE_READ_DATA|FILE_WRITE_DATA,
+                                       0,
+                                       NULL);
+       if (newsd == NULL) {
+               goto fail;
+       }
+       sd->dacl = security_acl_concatenate(frame,
+                                       newsd->dacl,
+                                       sd->dacl);
+       if (sd->dacl == NULL) {
+               goto fail;
+       }
+       status = cli_set_secdesc(cli, fnum, sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_set_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       fnum = (uint16_t)-1;
+
+       /* Try and open for FILE_WRITE_DATA */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               FILE_WRITE_DATA,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_OPEN,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("Open of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Now try and open for FILE_READ_DATA */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               FILE_READ_DATA,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_OPEN,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Restore clean slate. */
+       TALLOC_FREE(sd);
+       cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+
+
+       /* Create the test file. */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               GENERIC_ALL_ACCESS,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_CREATE,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Create of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /* Get the original SD. */
+       status = cli_query_secdesc(cli,
+                               fnum,
+                               frame,
+                               &sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_query_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+
+       /*
+        * Add an "authenticated users" ACE allowing READ_DATA,
+        * add an "owner-rights" denying READ_DATA,
+        * and an "authenticated users" ACE allowing WRITE_DATA.
+        */
+
+       newsd = security_descriptor_dacl_create(frame,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       SID_NT_AUTHENTICATED_USERS,
+                                       SEC_ACE_TYPE_ACCESS_ALLOWED,
+                                       FILE_READ_DATA,
+                                       0,
+                                       SID_OWNER_RIGHTS,
+                                       SEC_ACE_TYPE_ACCESS_DENIED,
+                                       FILE_READ_DATA,
+                                       0,
+                                       SID_NT_AUTHENTICATED_USERS,
+                                       SEC_ACE_TYPE_ACCESS_ALLOWED,
+                                       FILE_WRITE_DATA,
+                                       0,
+                                       NULL);
+       if (newsd == NULL) {
+               printf("newsd == NULL\n");
+               goto fail;
+       }
+       sd->dacl = security_acl_concatenate(frame,
+                                       newsd->dacl,
+                                       sd->dacl);
+       if (sd->dacl == NULL) {
+               printf("sd->dacl == NULL\n");
+               goto fail;
+       }
+       status = cli_set_secdesc(cli, fnum, sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_set_secdesc failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
+               goto fail;
+       }
+       fnum = (uint16_t)-1;
+
+       /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               FILE_READ_DATA|FILE_WRITE_DATA,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_READ|FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE,
+                               FILE_OPEN,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s - %s\n", fname, nt_errstr(status));
+               goto fail;
+       }
+
+       status = cli_close(cli, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed for %s (%s)\n",
+                       fname, nt_errstr(status));
                goto fail;
        }
 
+       cli_unlink(cli, fname,
+               FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+
        TALLOC_FREE(frame);
        return true;
 
   fail:
 
-       if (posix_cli) {
-               torture_close_connection(posix_cli);
-       }
-
        if (cli) {
-               if (fnum != -1) {
+               if (fnum != (uint16_t)-1) {
                        cli_close(cli, fnum);
                }
-               cli_unlink(cli, src,
-                       FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
-               cli_unlink(cli, dst,
+               cli_unlink(cli, fname,
                        FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
-               cli_rmdir(cli, dsrc);
-               cli_rmdir(cli, ddst);
-               cli_rmdir(cli, dname);
-
                torture_close_connection(cli);
        }
 
@@ -8063,6 +8440,152 @@ static bool run_mangle1(int dummy)
        return true;
 }
 
+static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
+                                                struct file_info *f,
+                                                const char *mask,
+                                                void *state)
+{
+       if (f->short_name == NULL) {
+               return NT_STATUS_OK;
+       }
+
+       if (strlen(f->short_name) == 0) {
+               return NT_STATUS_OK;
+       }
+
+       printf("unexpected shortname: %s\n", f->short_name);
+
+       return NT_STATUS_OBJECT_NAME_INVALID;
+}
+
+static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
+                                           struct file_info *f,
+                                           const char *mask,
+                                           void *state)
+{
+       char *name = state;
+
+       printf("name: %s\n", f->name);
+       fstrcpy(name, f->name);
+       return NT_STATUS_OK;
+}
+
+static bool run_mangle_illegal(int dummy)
+{
+       struct cli_state *cli = NULL;
+       struct cli_state *cli_posix = NULL;
+       const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
+       const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
+       char *mangled_path = NULL;
+       uint16_t fnum;
+       fstring name;
+       fstring alt_name;
+       NTSTATUS status;
+
+       printf("starting mangle-illegal test\n");
+
+       if (!torture_open_connection(&cli, 0)) {
+               return False;
+       }
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       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)) {
+               return false;
+       }
+
+       cli_rmdir(cli, "\\MANGLE_ILLEGAL");
+       status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("mkdir1 failed : %s\n", nt_errstr(status));
+               return False;
+       }
+
+       /*
+        * Create a file with illegal NTFS characters and test that we
+        * get a usable mangled name
+        */
+
+       cli_setatr(cli_posix, illegal_fname, 0, 0);
+       cli_posix_unlink(cli_posix, illegal_fname);
+
+       status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
+                               0600, &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("POSIX create of %s failed (%s)\n",
+                      illegal_fname, nt_errstr(status));
+               return false;
+       }
+
+       status = cli_close(cli_posix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("close failed (%s)\n", nt_errstr(status));
+               return false;
+       }
+
+       status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("cli_list failed: %s\n", nt_errstr(status));
+               return false;
+       }
+
+       mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
+       if (mangled_path == NULL) {
+               return false;
+       }
+
+       status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
+               TALLOC_FREE(mangled_path);
+               return false;
+       }
+       TALLOC_FREE(mangled_path);
+       cli_close(cli, fnum);
+
+       cli_setatr(cli_posix, illegal_fname, 0, 0);
+       cli_posix_unlink(cli_posix, illegal_fname);
+
+       /*
+        * Create a file with a long name and check that we got *no* short name.
+        */
+
+       status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
+                             FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
+                             0, 0, &fnum, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("open %s failed: %s\n", fname, nt_errstr(status));
+               return false;
+       }
+       cli_close(cli, fnum);
+
+       status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("cli_list failed\n");
+               return false;
+       }
+
+       cli_unlink(cli, fname, 0);
+       cli_rmdir(cli, "\\MANGLE_ILLEGAL");
+
+       if (!torture_close_connection(cli_posix)) {
+               return false;
+       }
+
+       if (!torture_close_connection(cli)) {
+               return false;
+       }
+
+       return true;
+}
+
 static size_t null_source(uint8_t *buf, size_t n, void *priv)
 {
        size_t *to_pull = (size_t *)priv;
@@ -9120,6 +9643,106 @@ static bool run_pidhigh(int dummy)
        return success;
 }
 
+/*
+  Test Windows open on a bad POSIX symlink.
+ */
+static bool run_symlink_open_test(int dummy)
+{
+       static struct cli_state *cli;
+       const char *fname = "non_existant_file";
+       const char *sname = "dangling_symlink";
+       uint16_t fnum = (uint16_t)-1;
+       bool correct = false;
+       NTSTATUS status;
+       TALLOC_CTX *frame = NULL;
+
+       frame = talloc_stackframe();
+
+       printf("Starting Windows bad symlink open test\n");
+
+       if (!torture_open_connection(&cli, 0)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+       status = torture_setup_unix_extensions(cli);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       /* Ensure nothing exists. */
+       cli_setatr(cli, fname, 0, 0);
+       cli_posix_unlink(cli, fname);
+       cli_setatr(cli, sname, 0, 0);
+       cli_posix_unlink(cli, sname);
+
+       /* Create a symlink pointing nowhere. */
+       status = cli_posix_symlink(cli, fname, sname);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_symlink of %s -> %s failed (%s)\n",
+                       sname,
+                       fname,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       /* Now ensure that a Windows open doesn't hang. */
+       status = cli_ntcreate(cli,
+                       sname,
+                       0,
+                       FILE_READ_DATA|FILE_WRITE_DATA,
+                       0,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                       FILE_OPEN_IF,
+                       0x0,
+                       0x0,
+                       &fnum,
+                       NULL);
+
+       /*
+        * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
+        * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
+        * we use O_NOFOLLOW on the server or not.
+        */
+       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
+           NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
+       {
+               correct = true;
+       } else {
+               printf("cli_ntcreate of %s returned %s - should return"
+                               " either (%s) or (%s)\n",
+                       sname,
+                       nt_errstr(status),
+                       nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
+                       nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
+               goto out;
+       }
+
+       correct = true;
+
+  out:
+
+       if (fnum != (uint16_t)-1) {
+               cli_close(cli, fnum);
+               fnum = (uint16_t)-1;
+       }
+
+       cli_setatr(cli, sname, 0, 0);
+       cli_posix_unlink(cli, sname);
+       cli_setatr(cli, fname, 0, 0);
+       cli_posix_unlink(cli, fname);
+
+       if (!torture_close_connection(cli)) {
+               correct = false;
+       }
+
+       TALLOC_FREE(frame);
+       return correct;
+}
+
 static bool run_local_substitute(int dummy)
 {
        bool ok = true;
@@ -10497,6 +11120,124 @@ static bool run_local_tdb_writer(int dummy)
        return true;
 }
 
+static bool run_local_canonicalize_path(int dummy)
+{
+       const char *src[] = {
+                       "/foo/..",
+                       "/..",
+                       "/foo/bar/../baz",
+                       "/foo/././",
+                       "/../foo",
+                       ".././././",
+                       ".././././../../../boo",
+                       "./..",
+                       NULL
+                       };
+       const char *dst[] = {
+                       "/",
+                       "/",
+                       "/foo/baz",
+                       "/foo",
+                       "/foo",
+                       "/",
+                       "/boo",
+                       "/",
+                       NULL
+                       };
+       unsigned int i;
+
+       for (i = 0; src[i] != NULL; i++) {
+               char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
+               if (d == NULL) {
+                       perror("talloc fail\n");
+                       return false;
+               }
+               if (strcmp(d, dst[i]) != 0) {
+                       d_fprintf(stderr,
+                               "canonicalize missmatch %s -> %s != %s",
+                               src[i], d, dst[i]);
+                       return false;
+               }
+               talloc_free(d);
+       }
+       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);
+       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)) {
+               d_fprintf(stderr, "smbXcli_negprot succeeded!\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 = smb1cli_session_setup_nt1_send(
+               ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
+               data_blob_null, data_blob_null, 0x40,
+               "Windows 2000 2195", "Windows 2000 5.0");
+       if (req == NULL) {
+               d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
+               return false;
+       }
+
+       ok = tevent_req_poll_ntstatus(req, ev, &status);
+       if (!ok) {
+               d_fprintf(stderr, "tevent_req_poll failed\n");
+               return false;
+       }
+
+       status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
+                                               NULL, NULL);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
+               d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
+                         "%s, expected NT_STATUS_CONNECTION_RESET\n",
+                         nt_errstr(status));
+               return false;
+       }
+
+       TALLOC_FREE(conn);
+
+       printf("starting ignore bad negprot\n");
+
+       return true;
+}
+
 static double create_procs(bool (*fn)(int), bool *result)
 {
        int i, status;
@@ -10639,6 +11380,7 @@ static struct {
        {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
        {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
        {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
+       {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
        {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
        {"ASYNC-ECHO", run_async_echo, 0},
        { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
@@ -10650,12 +11392,14 @@ static struct {
        {"XCOPY", run_xcopy, 0},
        {"RENAME", run_rename, 0},
        {"RENAME-ACCESS", run_rename_access, 0},
+       {"OWNER-RIGHTS", run_owner_rights, 0},
        {"DELETE", run_deletetest, 0},
        {"WILDDELETE", run_wild_deletetest, 0},
        {"DELETE-LN", run_deletetest_ln, 0},
        {"PROPERTIES", run_properties, 0},
        {"MANGLE", torture_mangle, 0},
        {"MANGLE1", run_mangle1, 0},
+       {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
        {"W2K", run_w2ktest, 0},
        {"TRANS2SCAN", torture_trans2_scan, 0},
        {"NTTRANSSCAN", torture_nttrans_scan, 0},
@@ -10684,6 +11428,7 @@ static struct {
        { "NOTIFY-BENCH2", run_notify_bench2 },
        { "NOTIFY-BENCH3", run_notify_bench3 },
        { "BAD-NBT-SESSION", run_bad_nbt_session },
+       { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
        { "SMB-ANY-CONNECT", run_smb_any_connect },
        { "NOTIFY-ONLINE", run_notify_online },
        { "SMB2-BASIC", run_smb2_basic },
@@ -10692,6 +11437,7 @@ static struct {
        { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
        { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
        { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
+       { "SMB2-FTRUNCATE", run_smb2_ftruncate },
        { "CLEANUP1", run_cleanup1 },
        { "CLEANUP2", run_cleanup2 },
        { "CLEANUP3", run_cleanup3 },
@@ -10730,6 +11476,7 @@ static struct {
        { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
        { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
        { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
+       { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
        { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
        {NULL, NULL, 0}};