* fhandler.cc (fhandler_base::facl): Drop CLASS_OBJ entry.

* fhandler_disk_file.cc (fhandler_disk_file::facl): Ditto in noacl case.
	* sec_acl.cc (getacl): Compute useful fake CLASS_OBJ and DEF_CLASS_OBJ
	permission bits based on how these values are generated on Linux.
	Add commants to explain what the code is doing.
	* security.cc (get_attribute_from_acl): Compute group permission based
	on the actual primary group permissions and all secondary user and group
	ACCESS_ALLOWED_ACEs to emulate Linux' behaviour more closely.
	(check_access): Fix typos im comment.
	* include/cygwin/acl.h (MIN_ACL_ENTRIES): Redefine as 3.
This commit is contained in:
Corinna Vinschen 2014-08-28 12:38:52 +00:00
parent c51ce2447a
commit 1a33a5c6d3
6 changed files with 78 additions and 27 deletions

View File

@ -1,3 +1,16 @@
2014-08-28 Corinna Vinschen <corinna@vinschen.de>
* fhandler.cc (fhandler_base::facl): Drop CLASS_OBJ entry.
* fhandler_disk_file.cc (fhandler_disk_file::facl): Ditto in noacl case.
* sec_acl.cc (getacl): Compute useful fake CLASS_OBJ and DEF_CLASS_OBJ
permission bits based on how these values are generated on Linux.
Add commants to explain what the code is doing.
* security.cc (get_attribute_from_acl): Compute group permission based
on the actual primary group permissions and all secondary user and group
ACCESS_ALLOWED_ACEs to emulate Linux' behaviour more closely.
(check_access): Fix typos im comment.
* include/cygwin/acl.h (MIN_ACL_ENTRIES): Redefine as 3.
2014-08-28 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Try the

View File

@ -1737,9 +1737,6 @@ fhandler_base::facl (int cmd, int nentries, aclent_t *aclbufp)
aclbufp[2].a_type = OTHER_OBJ;
aclbufp[2].a_id = ILLEGAL_GID;
aclbufp[2].a_perm = S_IROTH | S_IWOTH;
aclbufp[3].a_type = CLASS_OBJ;
aclbufp[3].a_id = ILLEGAL_GID;
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
res = MIN_ACL_ENTRIES;
}
break;

View File

@ -1045,9 +1045,6 @@ cant_access_acl:
aclbufp[2].a_type = OTHER_OBJ;
aclbufp[2].a_id = ILLEGAL_GID;
aclbufp[2].a_perm = st.st_mode & S_IRWXO;
aclbufp[3].a_type = CLASS_OBJ;
aclbufp[3].a_id = ILLEGAL_GID;
aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO;
res = MIN_ACL_ENTRIES;
}
}

View File

@ -1,6 +1,6 @@
/* cygwin/acl.h header file for Cygwin.
Copyright 1999, 2000, 2001, 2002, 2010 Red Hat, Inc.
Copyright 1999, 2000, 2001, 2002, 2010, 2014 Red Hat, Inc.
Written by C. Vinschen.
This file is part of Cygwin.
@ -25,7 +25,7 @@ extern "C" {
#define GETACL (0x1)
#define GETACLCNT (0x2)
#define MIN_ACL_ENTRIES (4) // minimal acl entries from GETACLCNT
#define MIN_ACL_ENTRIES (3) // minimal acl entries from GETACLCNT
#define MAX_ACL_ENTRIES (256) // max entries of each type
// Return values of aclcheck(3) in case of error */

View File

@ -309,9 +309,6 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
lacl[1].a_id = gid;
lacl[2].a_type = OTHER_OBJ;
lacl[2].a_id = ILLEGAL_GID;
lacl[3].a_type = CLASS_OBJ;
lacl[3].a_id = ILLEGAL_GID;
lacl[3].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
PACL acl;
BOOLEAN acl_exists;
@ -324,9 +321,11 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
}
int pos, i, types_def = 0;
int pgrp_pos = 1, def_pgrp_pos = -1;
mode_t class_perm = 0, def_class_perm = 0;
if (!acl_exists || !acl)
for (pos = 0; pos < 3; ++pos) /* Don't change CLASS_OBJ entry */
for (pos = 0; pos < 3; ++pos)
lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
else
{
@ -358,13 +357,13 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
}
else if (ace_sid == well_known_creator_group_sid)
{
type = GROUP_OBJ | ACL_DEFAULT;
type = DEF_GROUP_OBJ;
types_def |= type;
id = ILLEGAL_GID;
}
else if (ace_sid == well_known_creator_owner_sid)
{
type = USER_OBJ | ACL_DEFAULT;
type = DEF_USER_OBJ;
types_def |= type;
id = ILLEGAL_GID;
}
@ -376,7 +375,12 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
if (!(ace->Header.AceFlags & INHERIT_ONLY_ACE || type & ACL_DEFAULT))
{
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
{
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
/* Fix up CLASS_OBJ value. */
if (type == USER || type == GROUP)
class_perm |= lacl[pos].a_perm;
}
}
if ((ace->Header.AceFlags
& (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))
@ -389,13 +393,31 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
type |= ACL_DEFAULT;
types_def |= type;
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
{
getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType);
/* Fix up DEF_CLASS_OBJ value. */
if (type == DEF_USER || type == DEF_GROUP)
def_class_perm |= lacl[pos].a_perm;
/* And note the position of the DEF_GROUP_OBJ entry. */
else if (type == DEF_GROUP_OBJ)
def_pgrp_pos = pos;
}
}
}
/* If secondary user and group entries exist in the ACL, fake a matching
CLASS_OBJ entry. The CLASS_OBJ permissions are the or'ed permissions
of the primary group permissions and all secondary user and group
permissions. */
if (class_perm && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
lacl[pos].a_type = CLASS_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = class_perm | lacl[pgrp_pos].a_perm;
}
/* Ensure that the default acl contains at least
DEF_(USER|GROUP|OTHER)_OBJ entries. */
if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
/* Ensure that the default acl contains at
least DEF_(USER|GROUP|OTHER)_OBJ entries. */
if (!(types_def & USER_OBJ))
{
lacl[pos].a_type = DEF_USER_OBJ;
@ -408,6 +430,8 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
lacl[pos].a_type = DEF_GROUP_OBJ;
lacl[pos].a_id = gid;
lacl[pos].a_perm = lacl[1].a_perm;
/* Note the position of the DEF_GROUP_OBJ entry. */
def_pgrp_pos = pos;
pos++;
}
if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
@ -417,13 +441,18 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
lacl[pos].a_perm = lacl[2].a_perm;
pos++;
}
/* Include DEF_CLASS_OBJ if any named default ace exists. */
if ((types_def & (USER|GROUP)) && pos < MAX_ACL_ENTRIES)
{
lacl[pos].a_type = DEF_CLASS_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH;
}
}
/* If secondary user default and group default entries exist in the ACL,
fake a matching DEF_CLASS_OBJ entry. The DEF_CLASS_OBJ permissions are
the or'ed permissions of the primary group default permissions and all
secondary user and group default permissions. */
if (def_class_perm && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
{
lacl[pos].a_type = DEF_CLASS_OBJ;
lacl[pos].a_id = ILLEGAL_GID;
lacl[pos].a_perm = def_class_perm;
if (def_pgrp_pos >= 0)
lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
}
}
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)

View File

@ -314,6 +314,21 @@ get_attribute_from_acl (mode_t *attribute, PACL acl, PSID owner_sid,
*flags |= ((!(*anti & S_IXGRP)) ? S_IXGRP : 0)
| ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
}
else if (flags == &allow)
{
/* Simplified computation of additional group permissions based on
the CLASS_OBJ value. CLASS_OBJ represents the or'ed value of
the primary group permissions and all secondary user and group
permissions. FIXME: This only takes ACCESS_ALLOWED_ACEs into
account. The computation with additional ACCESS_DENIED_ACE
handling is much more complicated. */
if (ace->Mask & FILE_READ_BITS)
*flags |= S_IRGRP;
if (ace->Mask & FILE_WRITE_BITS)
*flags |= S_IWGRP;
if (ace->Mask & FILE_EXEC_BITS)
*flags |= S_IXGRP;
}
}
*attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID);
if (owner_sid && group_sid && RtlEqualSid (owner_sid, group_sid)
@ -1049,8 +1064,8 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
/* Samba override. Check security descriptor for Samba UNIX user and group
accounts and check if we have an RFC 2307 mapping to a Windows account.
Create a new security descriptor with all of the UNIX acocunts with
valid mapping replaced with their WIndows counterpart. */
Create a new security descriptor with all of the UNIX accounts with
valid mapping replaced with their Windows counterpart. */
static void
convert_samba_sd (security_descriptor &sd_ret)
{