This is the mail archive of the cygwin-cvs@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[newlib-cygwin] Only allow enabled groups as primary group


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

commit 59b3bd2aa6c6e3ab5d8b7af2bc6490c0ed0d9a8c
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Mar 23 17:51:03 2016 +0100

    Only allow enabled groups as primary group
    
    So far any group in the user's token could be used as primary group.
    Windows doesn't check if the primary group is enabled or not, it just
    has no meaning.  From a POSIXy point of view it can lead to weird
    results though.
    
    	* uinfo.cc (check_token_membership): New static function.
    	(internal_getlogin): Only allow enabled groups as primary group.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/uinfo.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 86b0101..d966dd1 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -113,6 +113,38 @@ cygheap_user::init ()
     system_printf("Cannot get dacl, %E");
 }
 
+/* Check if sid is an enabled SID in the token group list of the current
+   effective token.  Note that we only check for ENABLED groups, not for
+   INTEGRITY_ENABLED.  The latter just doesn't make sense in our scenario
+   of using the group as primary group.
+
+   This needs careful checking should we use check_token_membership in other
+   circumstances. */
+static bool
+check_token_membership (PSID sid)
+{
+  NTSTATUS status;
+  ULONG size;
+  tmp_pathbuf tp;
+  PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.w_get ();
+
+  /* If impersonated, use impersonation token. */
+  HANDLE tok = cygheap->user.issetuid () ? cygheap->user.primary_token ()
+					 : hProcToken;
+  status = NtQueryInformationToken (tok, TokenGroups, groups, 2 * NT_MAX_PATH,
+				    &size);
+  if (!NT_SUCCESS (status))
+    debug_printf ("NtQueryInformationToken (TokenGroups) %y", status);
+  else
+    {
+      for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+	if (RtlEqualSid (sid, groups->Groups[pg].Sid)
+	    && (groups->Groups[pg].Attributes & SE_GROUP_ENABLED))
+	  return true;
+    }
+  return false;
+}
+
 void
 internal_getlogin (cygheap_user &user)
 {
@@ -148,16 +180,23 @@ internal_getlogin (cygheap_user &user)
 		 disagree with gr_gid from the group file.  Overwrite it. */
 	      if ((grp2 = internal_getgrsid (gsid, &cldap)) && grp2 != grp)
 		myself->gid = pwd->pw_gid = grp2->gr_gid;
-	      /* Set primary group to the group in /etc/passwd. */
+	      /* Set primary group to the group in /etc/passwd, *iff*
+		 the group in /etc/passwd is in the token *and* enabled. */
 	      if (gsid != user.groups.pgsid)
 		{
-		  NTSTATUS status = NtSetInformationToken (hProcToken,
-							   TokenPrimaryGroup,
-							   &gsid, sizeof gsid);
+		  NTSTATUS status = STATUS_INVALID_PARAMETER;
+
+		  if (check_token_membership (gsid))
+		    {
+		      status = NtSetInformationToken (hProcToken,
+						      TokenPrimaryGroup,
+						      &gsid, sizeof gsid);
+		      if (!NT_SUCCESS (status))
+			debug_printf ("NtSetInformationToken "
+				      "(TokenPrimaryGroup), %y", status);
+		    }
 		  if (!NT_SUCCESS (status))
 		    {
-		      debug_printf ("NtSetInformationToken (TokenPrimaryGroup),"
-				    " %y", status);
 		      /* Revert the primary group setting and override the
 			 setting in the passwd entry. */
 		      if (pgrp)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]