Use NULL dey ACE rather than special Cygwin ACE
* sec_acl.cc: Change preceeding comment explaining new-style ACLs. Describe how to generate deny ACEs in more detail. Accommodate the fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than a special Cygwin ACE. Improve further comments. (CYG_ACE_NEW_STYLE): Define. (get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single NULL deny ACE if the inheritance flags say so. * sec_helper.cc (well_known_cygwin_sid): Remove. * security.h (well_known_cygwin_sid): Drop declaration. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
6326a8c0f3
commit
0411e86216
@ -1,3 +1,16 @@
|
|||||||
|
2015-04-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* sec_acl.cc: Change preceeding comment explaining new-style ACLs.
|
||||||
|
Describe how to generate deny ACEs in more detail. Accommodate the
|
||||||
|
fact that a NULL deny ACE is used for {DEF_}CLASS_OBJ, rather than
|
||||||
|
a special Cygwin ACE. Improve further comments.
|
||||||
|
(CYG_ACE_NEW_STYLE): Define.
|
||||||
|
(get_posix_access): Change from Cygwin ACE to NULL deny ACE. Fix
|
||||||
|
CLASS_OBJ handling to generate CLASS_OBJ and DEF_CLASS_OBJ from a single
|
||||||
|
NULL deny ACE if the inheritance flags say so.
|
||||||
|
* sec_helper.cc (well_known_cygwin_sid): Remove.
|
||||||
|
* security.h (well_known_cygwin_sid): Drop declaration.
|
||||||
|
|
||||||
2015-04-08 Corinna Vinschen <corinna@vinschen.de>
|
2015-04-08 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* include/cyggwin/acl.h (struct __acl16): Move from here...
|
* include/cyggwin/acl.h (struct __acl16): Move from here...
|
||||||
|
@ -27,23 +27,30 @@ details. */
|
|||||||
/* How does a correctly constructed new-style Windows ACL claiming to be a
|
/* How does a correctly constructed new-style Windows ACL claiming to be a
|
||||||
POSIX ACL look like?
|
POSIX ACL look like?
|
||||||
|
|
||||||
- Cygwin ACE (special bits, CLASS_OBJ).
|
- NULL ACE (special bits, CLASS_OBJ).
|
||||||
|
|
||||||
- If a USER entry has more permissions than any group, Everyone, or if it
|
- USER_OBJ deny. If the user has less permissions than the sum of CLASS_OBJ
|
||||||
has more permissions than allowed by the CLASS_OBJ entry:
|
(or GROUP_OBJ if CLASS_OBJ doesn't exist) and OTHER_OBJ, deny the excess
|
||||||
|
permissions so that group and other perms don't spill into the owner perms.
|
||||||
|
|
||||||
USER deny ACEs == POSIX allow
|
USER_OBJ deny ACE == ~USER_OBJ & (CLASS_OBJ | OTHER_OBJ)
|
||||||
& ^(mask | all group allows | Everyone allow)
|
or
|
||||||
|
USER_OBJ deny ACE == ~USER_OBJ & (GROUP_OBJ | OTHER_OBJ)
|
||||||
|
|
||||||
|
- USER deny. If a user has different permissions from CLASS_OBJ, or if the
|
||||||
|
user has less permissions than OTHER_OBJ, deny the excess permissions.
|
||||||
|
|
||||||
|
USER deny ACE == (USER ^ CLASS_OBJ) | (~USER & OTHER_OBJ)
|
||||||
|
|
||||||
- USER_OBJ allow ACE
|
- USER_OBJ allow ACE
|
||||||
- USER allow ACEs
|
- USER allow ACEs
|
||||||
|
|
||||||
The POSIX permissions returned for a USER entry are the allow bits alone!
|
The POSIX permissions returned for a USER entry are the allow bits alone!
|
||||||
|
|
||||||
- If a GROUP entry has more permissions than Everyone, or if it has more
|
- GROUP{_OBJ} deny. If a group has more permissions than CLASS_OBJ,
|
||||||
permissions than allowed by the CLASS_OBJ entry:
|
or less permissions than OTHER_OBJ, deny the excess permissions.
|
||||||
|
|
||||||
GROUP deny ACEs == POSIX allow & ^(mask | Everyone allow)
|
GROUP{_OBJ} deny ACEs == (GROUP & ~CLASS_OBJ) | (~GROUP & OTHER_OBJ)
|
||||||
|
|
||||||
- GROUP_OBJ allow ACE
|
- GROUP_OBJ allow ACE
|
||||||
- GROUP allow ACEs
|
- GROUP allow ACEs
|
||||||
@ -54,15 +61,16 @@ details. */
|
|||||||
|
|
||||||
Rinse and repeat for default ACEs with INHERIT flags set.
|
Rinse and repeat for default ACEs with INHERIT flags set.
|
||||||
|
|
||||||
- Default Cygwin ACE (S_ISGID, CLASS_OBJ). */
|
- Default NULL ACE (S_ISGID, CLASS_OBJ). */
|
||||||
|
|
||||||
/* POSIX <-> Win32 */
|
/* POSIX <-> Win32 */
|
||||||
|
|
||||||
/* Historically, these bits are stored in a NULL SID ACE. To distinguish
|
/* Historically, these bits are stored in a NULL SID ACE. To distinguish the
|
||||||
the new ACL style from the old one, we're now using an invented SID, the
|
new ACL style from the old one, we're using an access denied ACE, plus
|
||||||
Cygwin SID (S-1-0-1132029815). The new ACEs can exist twice in an ACL,
|
setting an as yet unused bit in the access mask. The new ACEs can exist
|
||||||
the "normal one" containg CLASS_OBJ and special bits, and the one with
|
twice in an ACL, the "normal one" containing CLASS_OBJ and special bits
|
||||||
INHERIT bit set to pass the DEF_CLASS_OBJ bits and the S_ISGID bit on. */
|
and the one with INHERIT bit set to pass the DEF_CLASS_OBJ bits and the
|
||||||
|
S_ISGID bit on. */
|
||||||
#define CYG_ACE_ISVTX 0x001 /* 0x200 <-> 0x001 */
|
#define CYG_ACE_ISVTX 0x001 /* 0x200 <-> 0x001 */
|
||||||
#define CYG_ACE_ISGID 0x002 /* 0x400 <-> 0x002 */
|
#define CYG_ACE_ISGID 0x002 /* 0x400 <-> 0x002 */
|
||||||
#define CYG_ACE_ISUID 0x004 /* 0x800 <-> 0x004 */
|
#define CYG_ACE_ISUID 0x004 /* 0x800 <-> 0x004 */
|
||||||
@ -81,6 +89,7 @@ details. */
|
|||||||
#define CYG_ACE_MASK_TO_WIN(val) \
|
#define CYG_ACE_MASK_TO_WIN(val) \
|
||||||
((((val) & S_IRWXO) << 3) \
|
((((val) & S_IRWXO) << 3) \
|
||||||
| CYG_ACE_MASK_VALID)
|
| CYG_ACE_MASK_VALID)
|
||||||
|
#define CYG_ACE_NEW_STYLE READ_CONTROL /* New style if set. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
searchace (aclent_t *aclp, int nentries, int type, uid_t id = ILLEGAL_UID)
|
searchace (aclent_t *aclp, int nentries, int type, uid_t id = ILLEGAL_UID)
|
||||||
@ -386,7 +395,9 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
|
|||||||
return set_file_sd (handle, pc, sd_ret, false);
|
return set_file_sd (handle, pc, sd_ret, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary access denied bits */
|
/* Temporary access denied bits used by getace and get_posix_access during
|
||||||
|
Windows ACL processing. These bits get removed before the created POSIX
|
||||||
|
ACL gets published. */
|
||||||
#define DENY_R 040000
|
#define DENY_R 040000
|
||||||
#define DENY_W 020000
|
#define DENY_W 020000
|
||||||
#define DENY_X 010000
|
#define DENY_X 010000
|
||||||
@ -545,44 +556,50 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
|
|||||||
|
|
||||||
if (ace_sid == well_known_null_sid)
|
if (ace_sid == well_known_null_sid)
|
||||||
{
|
{
|
||||||
/* Old-style or non-Cygwin ACL. Fetch only the special bits. */
|
/* Fetch special bits. */
|
||||||
attr |= CYG_ACE_ISBITS_TO_POSIX (ace->Mask);
|
attr |= CYG_ACE_ISBITS_TO_POSIX (ace->Mask);
|
||||||
continue;
|
if (ace->Header.AceType == ACCESS_DENIED_ACE_TYPE
|
||||||
}
|
&& ace->Mask & CYG_ACE_NEW_STYLE)
|
||||||
if (ace_sid == well_known_cygwin_sid)
|
|
||||||
{
|
|
||||||
/* New-style ACL. Note the fact that a mask value is present since
|
|
||||||
that changes how getace fetches the information. That's fine,
|
|
||||||
because the Cygwin SID ACE is supposed to precede all USER, GROUP
|
|
||||||
and GROUP_OBJ entries. Any ACL not created that way has been
|
|
||||||
rearranged by the Windows functionality to create the brain-dead
|
|
||||||
"canonical" ACL order and is broken anyway. */
|
|
||||||
attr |= CYG_ACE_ISBITS_TO_POSIX (ace->Mask);
|
|
||||||
if (ace->Mask & CYG_ACE_MASK_VALID)
|
|
||||||
{
|
{
|
||||||
new_style = true;
|
/* New-style ACL. Note the fact that a mask value is present
|
||||||
type = (ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
|
since that changes how getace fetches the information. That's
|
||||||
? DEF_CLASS_OBJ : CLASS_OBJ;
|
fine, because the Cygwin SID ACE is supposed to precede all
|
||||||
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type)) >= 0)
|
USER, GROUP and GROUP_OBJ entries. Any ACL not created that
|
||||||
|
way has been rearranged by the Windows functionality to create
|
||||||
|
the brain-dead "canonical" ACL order and is broken anyway. */
|
||||||
|
attr |= CYG_ACE_ISBITS_TO_POSIX (ace->Mask);
|
||||||
|
if (ace->Mask & CYG_ACE_MASK_VALID)
|
||||||
{
|
{
|
||||||
lacl[pos].a_type = type;
|
new_style = true;
|
||||||
lacl[pos].a_id = ILLEGAL_GID;
|
if (!(ace->Header.AceFlags & INHERIT_ONLY))
|
||||||
lacl[pos].a_perm = CYG_ACE_MASK_TO_POSIX (ace->Mask);
|
{
|
||||||
}
|
if ((pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ))
|
||||||
if (type == CLASS_OBJ) /* Needed for POSIX permissions. */
|
>= 0)
|
||||||
{
|
{
|
||||||
has_class_perm = true;
|
lacl[pos].a_type = CLASS_OBJ;
|
||||||
class_perm = lacl[pos].a_perm;
|
lacl[pos].a_id = ILLEGAL_GID;
|
||||||
}
|
lacl[pos].a_perm = CYG_ACE_MASK_TO_POSIX (ace->Mask);
|
||||||
else
|
}
|
||||||
{
|
has_class_perm = true;
|
||||||
has_def_class_perm = true;
|
class_perm = lacl[pos].a_perm;
|
||||||
def_class_perm = lacl[pos].a_perm;
|
}
|
||||||
|
if (ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
|
||||||
|
{
|
||||||
|
if ((pos = searchace (lacl, MAX_ACL_ENTRIES,
|
||||||
|
DEF_CLASS_OBJ)) >= 0)
|
||||||
|
{
|
||||||
|
lacl[pos].a_type = DEF_CLASS_OBJ;
|
||||||
|
lacl[pos].a_id = ILLEGAL_GID;
|
||||||
|
lacl[pos].a_perm = CYG_ACE_MASK_TO_POSIX (ace->Mask);
|
||||||
|
}
|
||||||
|
has_def_class_perm = true;
|
||||||
|
def_class_perm = lacl[pos].a_perm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ace_sid == owner_sid)
|
if (ace_sid == owner_sid)
|
||||||
{
|
{
|
||||||
type = USER_OBJ;
|
type = USER_OBJ;
|
||||||
id = uid;
|
id = uid;
|
||||||
|
@ -40,8 +40,6 @@ SECURITY_ATTRIBUTES NO_COPY_RO sec_all_nih =
|
|||||||
|
|
||||||
MKSID (well_known_null_sid, "S-1-0-0",
|
MKSID (well_known_null_sid, "S-1-0-0",
|
||||||
SECURITY_NULL_SID_AUTHORITY, 1, SECURITY_NULL_RID);
|
SECURITY_NULL_SID_AUTHORITY, 1, SECURITY_NULL_RID);
|
||||||
MKSID (well_known_cygwin_sid, "S-1-0-1132029815",
|
|
||||||
SECURITY_NULL_SID_AUTHORITY, 1, 0x43796777); /* "Cygw" */
|
|
||||||
MKSID (well_known_world_sid, "S-1-1-0",
|
MKSID (well_known_world_sid, "S-1-1-0",
|
||||||
SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID);
|
SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID);
|
||||||
MKSID (well_known_local_sid, "S-1-2-0",
|
MKSID (well_known_local_sid, "S-1-2-0",
|
||||||
|
@ -393,7 +393,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern cygpsid well_known_null_sid;
|
extern cygpsid well_known_null_sid;
|
||||||
extern cygpsid well_known_cygwin_sid;
|
|
||||||
extern cygpsid well_known_world_sid;
|
extern cygpsid well_known_world_sid;
|
||||||
extern cygpsid well_known_local_sid;
|
extern cygpsid well_known_local_sid;
|
||||||
extern cygpsid well_known_console_logon_sid;
|
extern cygpsid well_known_console_logon_sid;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user