]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: torture: Add a basic SMB2 SACL test.
authorJeremy Allison <jra@samba.org>
Fri, 17 Apr 2020 18:46:49 +0000 (11:46 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 21 Apr 2020 18:37:39 +0000 (18:37 +0000)
Shows bits needed to set/get a SACL.  We need a script within Samba to run this
as it depends on a user with SeSecurityPrivilege to work.

Test does the following:

1). Create a test file.
2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED.
    NB. SMB2-only behavior. SMB1 allows this as tested in SMB1-SYSTEM-SECURITY.
3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
5). Close (3).
6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
7). Write SACL. Success.
8). Close (4).
9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
10). Read SACL. Success.
11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
12). Close (9).
13 - and on error). Delete test file.

Passes against Windows 10.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/torture/proto.h
source3/torture/test_smb2.c
source3/torture/torture.c

index 73a28991735b2de58e420311d9e7b2376b176697..bae58ef9659862ab18f4554167b16c7cec219551 100644 (file)
@@ -103,6 +103,7 @@ bool run_smb2_session_reauth(int dummy);
 bool run_smb2_ftruncate(int dummy);
 bool run_smb2_dir_fsync(int dummy);
 bool run_smb2_path_slash(int dummy);
+bool run_smb2_sacl(int dummy);
 bool run_chain3(int dummy);
 bool run_local_conv_auth_info(int dummy);
 bool run_local_sprintf_append(int dummy);
index 4e6d103b339c1a0ea1022e07ee717c217d61e1e1..52f1c3976238bab7d7dd74d872d6cd81dc6bcefd 100644 (file)
@@ -29,6 +29,7 @@
 #include "auth_generic.h"
 #include "../librpc/ndr/libndr.h"
 #include "libsmb/clirap.h"
+#include "libsmb/cli_smb2_fnum.h"
 
 extern fstring host, workgroup, share, password, username, myname;
 extern struct cli_credentials *torture_creds;
@@ -2540,3 +2541,338 @@ bool run_smb2_path_slash(int dummy)
        (void)cli_unlink(cli, fname_noslash, 0);
        return true;
 }
+
+/*
+ * NB. This can only work against a server where
+ * the connecting user has been granted SeSecurityPrivilege.
+ *
+ *  1). Create a test file.
+ *  2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
+ *             NB. SMB2-only behavior.
+ *  3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
+ *  4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
+ *  5). Close (3).
+ *  6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
+ *  7). Write SACL. Success.
+ *  8). Close (4).
+ *  9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
+ *  10). Read SACL. Success.
+ *  11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
+ *  12). Close (9).
+ */
+
+bool run_smb2_sacl(int dummy)
+{
+       struct cli_state *cli = NULL;
+       NTSTATUS status;
+       struct security_descriptor *sd_dacl = NULL;
+       struct security_descriptor *sd_sacl = NULL;
+       const char *fname = "sacl_test_file";
+       uint16_t fnum = (uint16_t)-1;
+
+       printf("Starting SMB2-SACL\n");
+
+       if (!torture_init_connection(&cli)) {
+               return false;
+       }
+
+       status = smbXcli_negprot(cli->conn,
+                               cli->timeout,
+                               PROTOCOL_SMB2_02,
+                               PROTOCOL_SMB3_11);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("smbXcli_negprot returned %s\n", nt_errstr(status));
+               return false;
+       }
+
+       status = cli_session_setup_creds(cli, torture_creds);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_session_setup returned %s\n", nt_errstr(status));
+               return false;
+       }
+
+       status = cli_tree_connect(cli, share, "?????", NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_tree_connect returned %s\n", nt_errstr(status));
+               return false;
+       }
+
+       (void)cli_unlink(cli, fname, 0);
+
+       /* First create a file. */
+       status = cli_ntcreate(cli,
+                               fname,
+                               0,
+                               GENERIC_ALL_ACCESS,
+                               FILE_ATTRIBUTE_NORMAL,
+                               FILE_SHARE_NONE,
+                               FILE_CREATE,
+                               0,
+                               0,
+                               &fnum,
+                               NULL);
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("Create of %s failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+                goto fail;
+        }
+
+       cli_close(cli, fnum);
+       fnum = (uint16_t)-1;
+
+       /*
+        * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
+        * This should fail with NT_STATUS_ACCESS_DENIED - but
+        * only against an SMB2 server. SMB1 allows this as tested
+        * in SMB1-SYSTEM-SECURITY.
+        */
+
+       status = cli_smb2_create_fnum(cli,
+                       fname,
+                       SMB2_OPLOCK_LEVEL_NONE,
+                       SMB2_IMPERSONATION_IMPERSONATION,
+                       SEC_FLAG_SYSTEM_SECURITY, /* desired access */
+                       0, /* file_attributes, */
+                       FILE_SHARE_READ|
+                               FILE_SHARE_WRITE|
+                               FILE_SHARE_DELETE, /* share_access, */
+                       FILE_OPEN, /* create_disposition, */
+                       FILE_NON_DIRECTORY_FILE, /* create_options, */
+                       NULL, /* in_cblobs. */
+                       &fnum, /* fnum */
+                       NULL, /* smb_create_returns  */
+                       talloc_tos(), /* mem_ctx */
+                       NULL); /* out_cblobs */
+
+       if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
+               printf("SMB2-SACL-TEST can only work with a user "
+                       "who has been granted SeSecurityPrivilege.\n"
+                       "This is the "
+                       "\"Manage auditing and security log\""
+                       "privilege setting on Windows\n");
+               goto fail;
+       }
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
+                       "got %s - should fail with ACCESS_DENIED\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+       }
+
+       /*
+        * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
+        */
+
+       status = cli_smb2_create_fnum(cli,
+                       fname,
+                       SMB2_OPLOCK_LEVEL_NONE,
+                       SMB2_IMPERSONATION_IMPERSONATION,
+                       SEC_FLAG_SYSTEM_SECURITY|
+                               FILE_WRITE_ATTRIBUTES, /* desired access */
+                       0, /* file_attributes, */
+                       FILE_SHARE_READ|
+                               FILE_SHARE_WRITE|
+                               FILE_SHARE_DELETE, /* share_access, */
+                       FILE_OPEN, /* create_disposition, */
+                       FILE_NON_DIRECTORY_FILE, /* create_options, */
+                       NULL, /* in_cblobs. */
+                       &fnum, /* fnum */
+                       NULL, /* smb_create_returns  */
+                       talloc_tos(), /* mem_ctx */
+                       NULL); /* out_cblobs */
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
+                       "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       /* Create an SD with a SACL. */
+       sd_sacl = security_descriptor_sacl_create(talloc_tos(),
+                               0,
+                               NULL, /* owner. */
+                               NULL, /* group. */
+                               /* first ACE. */
+                               SID_WORLD,
+                               SEC_ACE_TYPE_SYSTEM_AUDIT,
+                               SEC_GENERIC_ALL,
+                               SEC_ACE_FLAG_FAILED_ACCESS,
+                               NULL);
+
+       if (sd_sacl == NULL) {
+               printf("Out of memory creating SACL\n");
+               goto fail;
+       }
+
+       /*
+        * Write the SACL SD. This should fail
+        * even though we have SEC_FLAG_SYSTEM_SECURITY,
+        * as it seems to also need WRITE_DAC access.
+        */
+       status = cli_smb2_set_security_descriptor(cli,
+                               fnum,
+                               SECINFO_DACL|SECINFO_SACL,
+                               sd_sacl);
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("Writing SACL on file %s got (%s) "
+                       "should have failed with ACCESS_DENIED.\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       /* And close. */
+       cli_smb2_close_fnum(cli, fnum);
+       fnum = (uint16_t)-1;
+
+       /*
+        * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
+        */
+
+       status = cli_smb2_create_fnum(cli,
+                       fname,
+                       SMB2_OPLOCK_LEVEL_NONE,
+                       SMB2_IMPERSONATION_IMPERSONATION,
+                       SEC_FLAG_SYSTEM_SECURITY|
+                               SEC_STD_WRITE_DAC, /* desired access */
+                       0, /* file_attributes, */
+                       FILE_SHARE_READ|
+                               FILE_SHARE_WRITE|
+                               FILE_SHARE_DELETE, /* share_access, */
+                       FILE_OPEN, /* create_disposition, */
+                       FILE_NON_DIRECTORY_FILE, /* create_options, */
+                       NULL, /* in_cblobs. */
+                       &fnum, /* fnum */
+                       NULL, /* smb_create_returns  */
+                       talloc_tos(), /* mem_ctx */
+                       NULL); /* out_cblobs */
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
+                       "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       /*
+        * Write the SACL SD. This should now succeed
+        * as we have both SEC_FLAG_SYSTEM_SECURITY
+        * and WRITE_DAC access.
+        */
+       status = cli_smb2_set_security_descriptor(cli,
+                               fnum,
+                               SECINFO_DACL|SECINFO_SACL,
+                               sd_sacl);
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_smb2_set_security_descriptor SACL "
+                       "on file %s failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       /* And close. */
+       cli_smb2_close_fnum(cli, fnum);
+       fnum = (uint16_t)-1;
+
+       /* We're done with the sacl we made. */
+       TALLOC_FREE(sd_sacl);
+
+       /*
+        * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
+        * This gives us access to the SACL.
+        */
+
+       status = cli_smb2_create_fnum(cli,
+                       fname,
+                       SMB2_OPLOCK_LEVEL_NONE,
+                       SMB2_IMPERSONATION_IMPERSONATION,
+                       SEC_FLAG_SYSTEM_SECURITY|
+                               FILE_READ_ATTRIBUTES, /* desired access */
+                       0, /* file_attributes, */
+                       FILE_SHARE_READ|
+                               FILE_SHARE_WRITE|
+                               FILE_SHARE_DELETE, /* share_access, */
+                       FILE_OPEN, /* create_disposition, */
+                       FILE_NON_DIRECTORY_FILE, /* create_options, */
+                       NULL, /* in_cblobs. */
+                       &fnum, /* fnum */
+                       NULL, /* smb_create_returns  */
+                       talloc_tos(), /* mem_ctx */
+                       NULL); /* out_cblobs */
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
+                       "FILE_READ_ATTRIBUTES) failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       /* Try and read the SACL - should succeed. */
+       status = cli_smb2_query_security_descriptor(cli,
+                               fnum,
+                               SECINFO_SACL,
+                               talloc_tos(),
+                               &sd_sacl);
+
+        if (!NT_STATUS_IS_OK(status)) {
+               printf("Read SACL from file %s failed (%s)\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       TALLOC_FREE(sd_sacl);
+
+       /*
+        * Try and read the DACL - should fail as we have
+        * no READ_DAC access.
+        */
+       status = cli_smb2_query_security_descriptor(cli,
+                               fnum,
+                               SECINFO_DACL,
+                               talloc_tos(),
+                               &sd_sacl);
+
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+               printf("Reading DACL on file %s got (%s) "
+                       "should have failed with ACCESS_DENIED.\n",
+                       fname,
+                       nt_errstr(status));
+               goto fail;
+        }
+
+       if (fnum != (uint16_t)-1) {
+               cli_smb2_close_fnum(cli, fnum);
+               fnum = (uint16_t)-1;
+       }
+
+       TALLOC_FREE(sd_dacl);
+       TALLOC_FREE(sd_sacl);
+
+       (void)cli_unlink(cli, fname, 0);
+       return true;
+
+  fail:
+
+       TALLOC_FREE(sd_dacl);
+       TALLOC_FREE(sd_sacl);
+
+       if (fnum != (uint16_t)-1) {
+               cli_smb2_close_fnum(cli, fnum);
+               fnum = (uint16_t)-1;
+       }
+
+       (void)cli_unlink(cli, fname, 0);
+       return false;
+}
index c49519130659611a86889bf215847d863df8dd7e..c3f387cd0e258c042ac7e63c39558c865e99696e 100644 (file)
@@ -14733,6 +14733,10 @@ static struct {
                .name  = "SMB1-SYSTEM-SECURITY",
                .fn    = run_smb1_system_security,
        },
+       {
+               .name  = "SMB2-SACL",
+               .fn    = run_smb2_sacl,
+       },
        {
                .name  = "CLEANUP1",
                .fn    = run_cleanup1,