]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: torture: Add samba3.smbtorture_s3.plain.POSIX-SYMLINK-CHMOD
authorJeremy Allison <jra@samba.org>
Mon, 19 Apr 2021 23:25:51 +0000 (16:25 -0700)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 20 Apr 2021 07:39:37 +0000 (07:39 +0000)
Shows we must protect against a null fsp handle when doing POSIX chmod on a symlink,
whether the symlink points to a real object or is dangling.

Add to knownfail for now. Commit 9722732b1867e359304594ada72ff40cd1341be5
removed the fsp == NULL protection for POSIX, and we need to put it back.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
selftest/knownfail.d/symlink_chmod [new file with mode: 0644]
source3/selftest/tests.py
source3/torture/proto.h
source3/torture/test_posix.c
source3/torture/torture.c

diff --git a/selftest/knownfail.d/symlink_chmod b/selftest/knownfail.d/symlink_chmod
new file mode 100644 (file)
index 0000000..8ebe2a7
--- /dev/null
@@ -0,0 +1,2 @@
+^samba3.smbtorture_s3.plain.*POSIX-SYMLINK-CHMOD
+^samba3.smbtorture_s3.crypt.*POSIX-SYMLINK-CHMOD
index 6cbed8cc8e2f67567a3b9eca890e7fbd2854e50e..11d0a41bda9e12fb04655ba6774106b220e85f79 100755 (executable)
@@ -263,6 +263,7 @@ posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA",
                "POSIX-READLINK",
                "POSIX-STAT",
                "POSIX-SYMLINK-PARENT",
+               "POSIX-SYMLINK-CHMOD",
               ]
 
 for t in posix_tests:
index dc27467ba64df5979bdb9646fd0e6d927c6f7966..57b1b5fea13edc4069bac4554b69ab4512cc6226 100644 (file)
@@ -90,6 +90,7 @@ bool run_posix_ls_single_test(int dummy);
 bool run_posix_readlink_test(int dummy);
 bool run_posix_stat_test(int dummy);
 bool run_posix_symlink_parent_test(int dummy);
+bool run_posix_symlink_chmod_test(int dummy);
 bool run_case_insensitive_create(int dummy);
 
 bool run_nbench2(int dummy);
index c2ce392ca767219be2532ff771b2556889c7bdc9..33a28866f9f862c1ad316b811ad5701c1065d692 100644 (file)
@@ -911,4 +911,141 @@ out:
        return correct;
 }
 
+/*
+  Ensure we get an error when doing chmod on a symlink,
+  whether it is pointing to a real object or dangling.
+ */
+bool run_posix_symlink_chmod_test(int dummy)
+{
+       TALLOC_CTX *frame = NULL;
+       struct cli_state *cli_unix = NULL;
+       NTSTATUS status;
+       uint16_t fnum = (uint16_t)-1;
+       const char *fname_real = "file_real";
+       const char *fname_real_symlink = "file_real_symlink";
+       const char *nonexist = "nonexist";
+       const char *nonexist_symlink = "dangling_symlink";
+       bool correct = false;
+
+       frame = talloc_stackframe();
+
+       printf("Starting POSIX-SYMLINK-CHMOD test\n");
+
+       if (!torture_open_connection(&cli_unix, 0)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       torture_conn_set_sockopt(cli_unix);
+
+       status = torture_setup_unix_extensions(cli_unix);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       /* Start with a clean slate. */
+       cli_posix_unlink(cli_unix, fname_real);
+       cli_posix_unlink(cli_unix, fname_real_symlink);
+       cli_posix_unlink(cli_unix, nonexist);
+       cli_posix_unlink(cli_unix, nonexist_symlink);
+
+       /* Create a real file. */
+       status = cli_posix_open(cli_unix,
+                               fname_real,
+                               O_RDWR|O_CREAT,
+                               0644,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open of %s failed error %s\n",
+                      fname_real,
+                      nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_unix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_close failed %s\n", nt_errstr(status));
+               goto out;
+       }
+       fnum = (uint16_t)-1;
+
+       /* Create symlink to real target. */
+       status = cli_posix_symlink(cli_unix,
+                                  fname_real,
+                                  fname_real_symlink);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_symlink of %s -> %s failed error %s\n",
+                      fname_real_symlink,
+                      fname_real,
+                      nt_errstr(status));
+               goto out;
+       }
+
+       /* We should not be able to chmod symlinks that point to something. */
+       status = cli_posix_chmod(cli_unix, fname_real_symlink, 0777);
+
+       /* This should fail with something other than server crashed. */
+       if (NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_chmod of %s succeeded (should have failed)\n",
+                       fname_real_symlink);
+               goto out;
+       }
+       if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
+               /* Oops. Server crashed. */
+               printf("cli_posix_chmod of %s failed error %s\n",
+                       fname_real_symlink,
+                       nt_errstr(status));
+               goto out;
+       }
+       /* Any other failure is ok. */
 
+       /* Now create symlink to non-existing target. */
+       status = cli_posix_symlink(cli_unix,
+                                  nonexist,
+                                  nonexist_symlink);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_symlink of %s -> %s failed error %s\n",
+                      nonexist_symlink,
+                      nonexist,
+                      nt_errstr(status));
+               goto out;
+       }
+
+       /* We should not be able to chmod symlinks that point to nothing. */
+       status = cli_posix_chmod(cli_unix, nonexist_symlink, 0777);
+
+       /* This should fail with something other than server crashed. */
+       if (NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_chmod of %s succeeded (should have failed)\n",
+                       nonexist_symlink);
+               goto out;
+       }
+       if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
+               /* Oops. Server crashed. */
+               printf("cli_posix_chmod of %s failed error %s\n",
+                       nonexist_symlink,
+                       nt_errstr(status));
+               goto out;
+       }
+
+       /* Any other failure is ok. */
+       printf("POSIX-SYMLINK-CHMOD test passed (expected failure was %s)\n",
+                       nt_errstr(status));
+       correct = true;
+
+out:
+       if (fnum != (uint16_t)-1) {
+               cli_close(cli_unix, fnum);
+       }
+       cli_posix_unlink(cli_unix, fname_real);
+       cli_posix_unlink(cli_unix, fname_real_symlink);
+       cli_posix_unlink(cli_unix, nonexist);
+       cli_posix_unlink(cli_unix, nonexist_symlink);
+
+       if (!torture_close_connection(cli_unix)) {
+               correct = false;
+       }
+
+       TALLOC_FREE(frame);
+       return correct;
+}
index a46a252bc1963033f70367a88199fae3d564f350..68e2cd2ba20e5b55fd0d6268cc1ebf5d7e05f3ff 100644 (file)
@@ -14951,6 +14951,10 @@ static struct {
                .name  = "POSIX-SYMLINK-PARENT",
                .fn    = run_posix_symlink_parent_test,
        },
+       {
+               .name  = "POSIX-SYMLINK-CHMOD",
+               .fn    = run_posix_symlink_chmod_test,
+       },
        {
                .name  = "WINDOWS-BAD-SYMLINK",
                .fn    = run_symlink_open_test,