#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;
(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;
+}