https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1c144ed142224cd112c1c9177a4231bef7975f9f

commit 1c144ed142224cd112c1c9177a4231bef7975f9f
Author: Corinna Vinschen <cori...@vinschen.de>
Date:   Thu Mar 19 18:27:03 2015 +0100

    Handle S_ISGID bit and multiple ACEs for owner
    
        * sec_acl.cc (get_posix_access): Handle multiple ACEs for the
        owner and primary group of the file.  Handle the default primary
        group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
        set.  Add comments.  Minor code rearrangements.
    
    Signed-off-by: Corinna Vinschen <cori...@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog  |  7 +++++++
 winsup/cygwin/sec_acl.cc | 41 ++++++++++++++++++++++++++++++++++++-----
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 5d45cdc..260f469 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2015-03-19  Corinna Vinschen  <cori...@vinschen.de>
+
+       * sec_acl.cc (get_posix_access): Handle multiple ACEs for the
+       owner and primary group of the file.  Handle the default primary
+       group ACE as DEF_GROUP_OBJ entry if the directory has the S_ISGID bit
+       set.  Add comments.  Minor code rearrangements.
+
 2015-03-18  Corinna Vinschen  <cori...@vinschen.de>
 
        Preliminary read side implementation of new permission handling.
diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc
index a93e191..aa18339 100644
--- a/winsup/cygwin/sec_acl.cc
+++ b/winsup/cygwin/sec_acl.cc
@@ -456,10 +456,16 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
   int pos, type, id;
 
   bool new_style = false;
+  bool saw_user_obj = false;
+  bool saw_group_obj = false;
+  bool saw_def_group_obj = false;
+  bool has_class_perm = false;
+  bool has_def_class_perm = false;
+
+  mode_t class_perm = 0;
+  mode_t def_class_perm = 0;
   int types_def = 0;
   int def_pgrp_pos = -1;
-  bool has_class_perm = false, has_def_class_perm = false;
-  mode_t class_perm = 0, def_class_perm = 0;
 
   if (aclbufp && nentries < MIN_ACL_ENTRIES)
     {
@@ -561,8 +567,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
              new_style = true;
              type = (ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
                     ? DEF_CLASS_OBJ : CLASS_OBJ;
-             if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, ILLEGAL_GID))
-                 >= 0)
+             if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type)) >= 0)
                {
                  lacl[pos].a_type = type;
                  lacl[pos].a_id = ILLEGAL_GID;
@@ -607,6 +612,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
          type = DEF_GROUP_OBJ;
          types_def |= type;
          id = ILLEGAL_GID;
+         saw_def_group_obj = true;
        }
       else
        {
@@ -616,6 +622,23 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
        }
       if (!(ace->Header.AceFlags & INHERIT_ONLY || type & ACL_DEFAULT))
        {
+         if (type == USER_OBJ)
+           {
+             /* If we get a second entry for the owner, it's an additional
+                USER entry.  This can happen when chown'ing a file. */
+             if (saw_user_obj)
+               type = USER;
+             if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+               saw_user_obj = true;
+           }
+         else if (type == GROUP_OBJ)
+           {
+             /* Same for the primary group. */
+             if (saw_group_obj)
+               type = GROUP;
+             if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+               saw_group_obj = true;
+           }
          if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)
            {
              getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType,
@@ -636,7 +659,15 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
          if (type == USER_OBJ)
            type = USER;
          else if (type == GROUP_OBJ)
-           type = GROUP;
+           {
+             /* If the SGID bit is set, the inheritable entry for the
+                primary group is, in fact, the DEF_GROUP_OBJ entry,
+                so don't change the type to GROUP in this case. */
+             if (!new_style || saw_def_group_obj || !(attr & S_ISGID))
+               type = GROUP;
+             else if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE)
+               saw_def_group_obj = true;
+           }
          type |= ACL_DEFAULT;
          types_def |= type;
          if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0)

Reply via email to