From: Jeremy Allison Date: Fri, 17 Apr 2020 18:46:49 +0000 (-0700) Subject: s3: torture: Add a basic SMB2 SACL test. X-Git-Tag: ldb-2.2.0~904 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad5f6b82c39bd0905aa26514ef239f6161612b11;p=thirdparty%2Fsamba.git s3: torture: Add a basic SMB2 SACL test. 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 Reviewed-by: Ralph Boehme --- diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 73a28991735..bae58ef9659 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -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); diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c index 4e6d103b339..52f1c397623 100644 --- a/source3/torture/test_smb2.c +++ b/source3/torture/test_smb2.c @@ -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; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index c4951913065..c3f387cd0e2 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -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,