mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3: torture: Add a test for setting and getting ACLs on stream handles (SMB2-STREAM-ACL).
It shows this isn't done correctly for streams_xattr. A common config is: vfs_objects = streams_xattr acl_xattr to store both streams and Windows ACLs in xattrs. Unfortunately getting and setting ACLs using handles opened on stream files isn't being done correctly in Samba. This test passes against Windows 10. This adds tests that prove this doesn't work. Next patch will add the fix and remove the knownfail. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
9cff0a0c11
commit
c7762a2bee
1
selftest/knownfail.d/stream-acl
Normal file
1
selftest/knownfail.d/stream-acl
Normal file
@ -0,0 +1 @@
|
||||
^samba3.smbtorture_s3.plain.SMB2-STREAM-ACL.smbtorture\(fileserver\)
|
@ -227,6 +227,21 @@ plantestsuite("samba3.smbtorture_s3.smb1.MSDFS-ATTRIBUTE",
|
||||
"-mNT1",
|
||||
"-f msdfs-src1"])
|
||||
|
||||
#
|
||||
# SMB2-STREAM-ACL needs to run against a special share - vfs_wo_fruit
|
||||
#
|
||||
plantestsuite("samba3.smbtorture_s3.plain.%s" % "SMB2-STREAM-ACL",
|
||||
"fileserver",
|
||||
[os.path.join(samba3srcdir,
|
||||
"script/tests/test_smbtorture_s3.sh"),
|
||||
'SMB2-STREAM-ACL',
|
||||
'//$SERVER_IP/vfs_wo_fruit',
|
||||
'$USERNAME',
|
||||
'$PASSWORD',
|
||||
smbtorture3,
|
||||
"",
|
||||
"-l $LOCAL_PATH"])
|
||||
|
||||
shares = [
|
||||
"vfs_aio_pthread_async_dosmode_default1",
|
||||
"vfs_aio_pthread_async_dosmode_default2",
|
||||
|
@ -110,6 +110,7 @@ bool run_smb2_dir_fsync(int dummy);
|
||||
bool run_smb2_path_slash(int dummy);
|
||||
bool run_smb2_sacl(int dummy);
|
||||
bool run_smb2_quota1(int dummy);
|
||||
bool run_smb2_stream_acl(int dummy);
|
||||
bool run_chain3(int dummy);
|
||||
bool run_local_conv_auth_info(int dummy);
|
||||
bool run_local_sprintf_append(int dummy);
|
||||
|
@ -2937,3 +2937,210 @@ bool run_smb2_quota1(int dummy)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool run_smb2_stream_acl(int dummy)
|
||||
{
|
||||
struct cli_state *cli = NULL;
|
||||
NTSTATUS status;
|
||||
uint16_t fnum = (uint16_t)-1;
|
||||
const char *fname = "stream_acl_test_file";
|
||||
const char *sname = "stream_acl_test_file:streamname";
|
||||
struct security_descriptor *sd_dacl = NULL;
|
||||
bool ret = false;
|
||||
|
||||
printf("SMB2 stream acl\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;
|
||||
}
|
||||
|
||||
/* Ensure file doesn't exist. */
|
||||
(void)cli_unlink(cli, fname, 0);
|
||||
|
||||
/* Create the 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;
|
||||
}
|
||||
|
||||
/* Close the handle. */
|
||||
cli_smb2_close_fnum(cli, fnum);
|
||||
fnum = (uint16_t)-1;
|
||||
|
||||
/* Create the stream. */
|
||||
status = cli_ntcreate(cli,
|
||||
sname,
|
||||
0,
|
||||
FILE_READ_DATA|
|
||||
SEC_STD_READ_CONTROL|
|
||||
SEC_STD_WRITE_DAC,
|
||||
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",
|
||||
sname,
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Close the handle. */
|
||||
cli_smb2_close_fnum(cli, fnum);
|
||||
fnum = (uint16_t)-1;
|
||||
|
||||
/*
|
||||
* Open the stream - for Samba this ensures
|
||||
* we prove we have a pathref fsp.
|
||||
*/
|
||||
status = cli_ntcreate(cli,
|
||||
sname,
|
||||
0,
|
||||
FILE_READ_DATA|
|
||||
SEC_STD_READ_CONTROL|
|
||||
SEC_STD_WRITE_DAC,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_NONE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
0,
|
||||
&fnum,
|
||||
NULL);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Open of %s failed (%s)\n",
|
||||
sname,
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Read the security descriptor off the stream handle. */
|
||||
status = cli_query_security_descriptor(cli,
|
||||
fnum,
|
||||
SECINFO_DACL,
|
||||
talloc_tos(),
|
||||
&sd_dacl);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Reading DACL on stream %s got (%s)\n",
|
||||
sname,
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
|
||||
sd_dacl->dacl->num_aces < 1) {
|
||||
printf("Invalid DACL returned on stream %s "
|
||||
"(this should not happen)\n",
|
||||
sname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure it allows FILE_READ_DATA in the first ace.
|
||||
* It always should.
|
||||
*/
|
||||
if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
|
||||
printf("DACL->ace[0] returned on stream %s "
|
||||
"doesn't have read access (should not happen)\n",
|
||||
sname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Remove FILE_READ_DATA from the first ace and set. */
|
||||
sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
|
||||
|
||||
status = cli_set_security_descriptor(cli,
|
||||
fnum,
|
||||
SECINFO_DACL,
|
||||
sd_dacl);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Setting DACL on stream %s got (%s)\n",
|
||||
sname,
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
TALLOC_FREE(sd_dacl);
|
||||
|
||||
/* Read again and check it changed. */
|
||||
status = cli_query_security_descriptor(cli,
|
||||
fnum,
|
||||
SECINFO_DACL,
|
||||
talloc_tos(),
|
||||
&sd_dacl);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Reading DACL on stream %s got (%s)\n",
|
||||
sname,
|
||||
nt_errstr(status));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
|
||||
sd_dacl->dacl->num_aces < 1) {
|
||||
printf("Invalid DACL (1) returned on stream %s "
|
||||
"(this should not happen)\n",
|
||||
sname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* FILE_READ_DATA should be gone from the first ace. */
|
||||
if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
|
||||
printf("DACL on stream %s did not change\n",
|
||||
sname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
fail:
|
||||
|
||||
if (fnum != (uint16_t)-1) {
|
||||
cli_smb2_close_fnum(cli, fnum);
|
||||
fnum = (uint16_t)-1;
|
||||
}
|
||||
|
||||
(void)cli_unlink(cli, fname, 0);
|
||||
return ret;
|
||||
}
|
||||
|
@ -15217,6 +15217,10 @@ static struct {
|
||||
.name = "SMB2-QUOTA1",
|
||||
.fn = run_smb2_quota1,
|
||||
},
|
||||
{
|
||||
.name = "SMB2-STREAM-ACL",
|
||||
.fn = run_smb2_stream_acl,
|
||||
},
|
||||
{
|
||||
.name = "CLEANUP1",
|
||||
.fn = run_cleanup1,
|
||||
|
Loading…
Reference in New Issue
Block a user