[newlib-cygwin/main] Cygwin: get_posix_access: move umask masking to the end
Corinna Vinschen
corinna@sourceware.org
Wed Jan 15 12:39:08 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0e6d36766c8358b27ba9c655a88647b41adc2914
commit 0e6d36766c8358b27ba9c655a88647b41adc2914
Author: Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Wed Jan 15 12:26:06 2025 +0100
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Wed Jan 15 12:27:03 2025 +0100
Cygwin: get_posix_access: move umask masking to the end
umask handling for new file gets overriden by subsequent merging of
permissions in Windows-generated ACLs. Fix this by performing
umask masking after all other ACL manipulations.
Fixes: a8716448cecc ("Simplify "Windows-standard-like" permissions")
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/sec/acl.cc | 190 +++++++++++++++++++++++------------------------
1 file changed, 95 insertions(+), 95 deletions(-)
diff --git a/winsup/cygwin/sec/acl.cc b/winsup/cygwin/sec/acl.cc
index aab567804933..9e041acc1203 100644
--- a/winsup/cygwin/sec/acl.cc
+++ b/winsup/cygwin/sec/acl.cc
@@ -1016,101 +1016,6 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
}
}
}
- /* If this is a just created file, and this is an ACL with only standard
- entries, or if standard POSIX permissions are missing (probably no
- inherited ACEs so created from a default DACL), assign the permissions
- specified by the file creation mask. The values get masked by the
- actually requested permissions by the caller per POSIX 1003.1e draft 17. */
- if (just_created)
- {
- mode_t perms = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
- if (standard_ACEs_only || !saw_user_obj)
- lacl[0].a_perm = (perms >> 6) & S_IRWXO;
- if (standard_ACEs_only || !saw_group_obj)
- lacl[1].a_perm = (perms >> 3) & S_IRWXO;
- if (standard_ACEs_only || !saw_other_obj)
- lacl[2].a_perm = perms & S_IRWXO;
- }
- /* If this is an old-style or non-Cygwin ACL, and 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 (!new_style && has_class_perm
- && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
- {
- lacl[pos].a_type = CLASS_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- class_perm |= lacl[1].a_perm;
- lacl[pos].a_perm = class_perm;
- aclsid[pos] = well_known_null_sid;
- }
- /* For ptys, fake a mask if the admins group is neither owner nor group.
- In that case we have an extra ACE for the admins group, and we need a
- CLASS_OBJ to get a valid POSIX ACL. However, Windows filters the ACE
- Mask value so it only reflects the bit values supported by the object
- type. The result is that we can't set an explicit CLASS_OBJ value for
- ptys in the NULL SID ACE. */
- else if (S_ISCHR (attr) && owner_sid != well_known_admins_sid
- && group_sid != well_known_admins_sid
- && (pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ)) >= 0)
- {
- lacl[pos].a_type = CLASS_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */
- aclsid[pos] = well_known_null_sid;
- }
- /* 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)
- {
- if (!(types_def & USER_OBJ))
- {
- lacl[pos].a_type = DEF_USER_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- lacl[pos].a_perm = lacl[0].a_perm;
- aclsid[pos] = well_known_creator_owner_sid;
- pos++;
- }
- if (!(types_def & GROUP_OBJ) && pos < MAX_ACL_ENTRIES)
- {
- lacl[pos].a_type = DEF_GROUP_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- lacl[pos].a_perm = lacl[1].a_perm;
- /* If owner == group, the owner perms should be used. */
- if (owner_eq_group)
- lacl[pos].a_perm |= lacl[0].a_perm;
- /* Note the position of the DEF_GROUP_OBJ entry. */
- def_pgrp_pos = pos;
- aclsid[pos] = well_known_creator_group_sid;
- pos++;
- }
- if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
- {
- lacl[pos].a_type = DEF_OTHER_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- lacl[pos].a_perm = lacl[2].a_perm;
- aclsid[pos] = well_known_world_sid;
- }
- }
- /* If this is an old-style or non-Cygwin ACL, and 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 def.
- permissions. */
- if (!new_style && has_def_class_perm
- && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
- {
- lacl[pos].a_type = DEF_CLASS_OBJ;
- lacl[pos].a_id = ACL_UNDEFINED_ID;
- lacl[pos].a_perm = def_class_perm;
- if (def_pgrp_pos >= 0)
- lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
- aclsid[pos] = well_known_null_sid;
- }
-
- /* Make sure `pos' contains the number of used entries in lacl. */
- if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
- pos = MAX_ACL_ENTRIES;
/* For old-style or non-Cygwin ACLs, check for merging permissions. */
if (!new_style)
@@ -1199,11 +1104,106 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
lacl[idx].a_perm |= lacl[obj_idx].a_perm;
}
}
+ /* If this is an old-style or non-Cygwin ACL, and 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 (!new_style && has_class_perm
+ && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
+ {
+ lacl[pos].a_type = CLASS_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ class_perm |= lacl[1].a_perm;
+ lacl[pos].a_perm = class_perm;
+ aclsid[pos] = well_known_null_sid;
+ }
+ /* For ptys, fake a mask if the admins group is neither owner nor group.
+ In that case we have an extra ACE for the admins group, and we need a
+ CLASS_OBJ to get a valid POSIX ACL. However, Windows filters the ACE
+ Mask value so it only reflects the bit values supported by the object
+ type. The result is that we can't set an explicit CLASS_OBJ value for
+ ptys in the NULL SID ACE. */
+ else if (S_ISCHR (attr) && owner_sid != well_known_admins_sid
+ && group_sid != well_known_admins_sid
+ && (pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ)) >= 0)
+ {
+ lacl[pos].a_type = CLASS_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */
+ aclsid[pos] = well_known_null_sid;
+ }
+ /* 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)
+ {
+ if (!(types_def & USER_OBJ))
+ {
+ lacl[pos].a_type = DEF_USER_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ lacl[pos].a_perm = lacl[0].a_perm;
+ aclsid[pos] = well_known_creator_owner_sid;
+ pos++;
+ }
+ if (!(types_def & GROUP_OBJ) && pos < MAX_ACL_ENTRIES)
+ {
+ lacl[pos].a_type = DEF_GROUP_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ lacl[pos].a_perm = lacl[1].a_perm;
+ /* If owner == group, the owner perms should be used. */
+ if (owner_eq_group)
+ lacl[pos].a_perm |= lacl[0].a_perm;
+ /* Note the position of the DEF_GROUP_OBJ entry. */
+ def_pgrp_pos = pos;
+ aclsid[pos] = well_known_creator_group_sid;
+ pos++;
+ }
+ if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
+ {
+ lacl[pos].a_type = DEF_OTHER_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ lacl[pos].a_perm = lacl[2].a_perm;
+ aclsid[pos] = well_known_world_sid;
+ }
+ }
+ /* If this is an old-style or non-Cygwin ACL, and 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 def.
+ permissions. */
+ if (!new_style && has_def_class_perm
+ && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
+ {
+ lacl[pos].a_type = DEF_CLASS_OBJ;
+ lacl[pos].a_id = ACL_UNDEFINED_ID;
+ lacl[pos].a_perm = def_class_perm;
+ if (def_pgrp_pos >= 0)
+ lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
+ aclsid[pos] = well_known_null_sid;
+ }
+
+ /* Make sure `pos' contains the number of used entries in lacl. */
+ if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
+ pos = MAX_ACL_ENTRIES;
/* If owner SID == group SID (Microsoft Accounts) merge group perms into
user perms but leave group perms intact. That's a fake, but it allows
to keep track of the POSIX group perms without much effort. */
if (owner_eq_group)
lacl[0].a_perm |= lacl[1].a_perm;
+ /* If this is a just created file, and this is an ACL with only standard
+ entries, or if standard POSIX permissions are missing (probably no
+ inherited ACEs so created from a default DACL), assign the permissions
+ specified by the file creation mask. The values get masked by the
+ actually requested permissions by the caller per POSIX 1003.1e draft 17. */
+ if (just_created)
+ {
+ mode_t perms = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
+ if (standard_ACEs_only || !saw_user_obj)
+ lacl[0].a_perm = (perms >> 6) & S_IRWXO;
+ if (standard_ACEs_only || !saw_group_obj)
+ lacl[1].a_perm = (perms >> 3) & S_IRWXO;
+ if (standard_ACEs_only || !saw_other_obj)
+ lacl[2].a_perm = perms & S_IRWXO;
+ }
/* Construct POSIX permission bits. Fortunately we know exactly where
to fetch the affecting bits from, at least as long as the array
hasn't been sorted. */
More information about the Cygwin-cvs
mailing list