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] setuid: Create token from scratch without credentials of caller


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

commit 205862ed08649df8f50b926a2c58c963f571b044
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Wed Feb 17 16:40:27 2016 +0100

    setuid: Create token from scratch without credentials of caller
    
    	* sec_auth.cc (get_token_group_sidlist): Drop auth_luid and
    	auth_pos parameter.  Remove code adding a logon SID.
    	(get_initgroups_sidlist): Drop auth_luid and auth_pos parameter.
    	Drop in call to get_token_group_sidlist. Accommodate in callers.
    	(get_setgroups_sidlist): Ditto.
    	(create_token): Explicitely set auth_luid to ANONYMOUS_LOGON_LUID
    	or LOCALSERVICE_LUID depending on OS.  Explain why.
    	Remove handling of logon SID since we don't generate one anymore.
    	(lsaauth): Drop now unused local variable auth_luid and auth_pos.
    	* wincap.h (wincaps::has_broken_whoami): New element.
    	* wincap.cc: Implement above element throughout.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/sec_auth.cc | 55 +++++++++++++++++------------------------------
 winsup/cygwin/wincap.cc   |  7 ++++++
 winsup/cygwin/wincap.h    |  2 ++
 3 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index d44cb2d..ba29339 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -503,10 +503,8 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
 }
 
 static void
-get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
-			 LUID auth_luid, int &auth_pos)
+get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
 {
-  auth_pos = -1;
   if (my_grps)
     {
       grp_list += well_known_local_sid;
@@ -538,16 +536,6 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
       grp_list *= well_known_interactive_sid;
       grp_list *= well_known_users_sid;
     }
-  if (get_ll (auth_luid) != 999LL) /* != SYSTEM_LUID */
-    {
-      for (DWORD i = 0; i < my_grps->GroupCount; ++i)
-	if (my_grps->Groups[i].Attributes & SE_GROUP_LOGON_ID)
-	  {
-	    grp_list += my_grps->Groups[i].Sid;
-	    auth_pos = grp_list.count () - 1;
-	    break;
-	  }
-    }
 }
 
 bool
@@ -589,14 +577,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid)
 
 static bool
 get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
-			PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos)
+			PTOKEN_GROUPS my_grps)
 {
   grp_list *= well_known_world_sid;
   grp_list *= well_known_authenticated_users_sid;
-  if (well_known_system_sid == usersid)
-    auth_pos = -1;
-  else
-    get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);
+  if (well_known_system_sid != usersid)
+    get_token_group_sidlist (grp_list, my_grps);
   if (!get_server_groups (grp_list, usersid))
     return false;
 
@@ -607,12 +593,11 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
 
 static void
 get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
-		       PTOKEN_GROUPS my_grps, user_groups &groups,
-		       LUID auth_luid, int &auth_pos)
+		       PTOKEN_GROUPS my_grps, user_groups &groups)
 {
   tmp_list *= well_known_world_sid;
   tmp_list *= well_known_authenticated_users_sid;
-  get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);
+  get_token_group_sidlist (tmp_list, my_grps);
   get_server_groups (tmp_list, usersid);
   for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
     tmp_list += groups.sgsids.sids[gidx];
@@ -891,7 +876,16 @@ create_token (cygsid &usersid, user_groups &new_groups)
   SECURITY_QUALITY_OF_SERVICE sqos =
     { sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
   OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };
-  LUID auth_luid = SYSTEM_LUID;
+  /* Up to Windows 7, when using a authwentication LUID other than "Anonymous",
+     Windows whoami prints the wrong username, the one from the login session,
+     not the one from the actual user token of the process.  This is apparently
+     fixed in Windows 8.  However, starting with Windows 8, access rights of
+     the anonymous logon session is further restricted.  Therefore we create
+     the new user token with the authentication id of the local service
+     account.  Hopefully that's sufficient. */
+  const LUID auth_luid_7 = ANONYMOUS_LOGON_LUID;
+  const LUID auth_luid_8 = LOCALSERVICE_LUID;
+  LUID auth_luid = wincap.has_broken_whoami () ? auth_luid_7 : auth_luid_8;
   LARGE_INTEGER exp = { QuadPart:INT64_MAX };
 
   TOKEN_USER user;
@@ -940,8 +934,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
 	  if (!NT_SUCCESS (status))
 	    debug_printf ("NtQueryInformationToken(hProcToken, "
 			  "TokenStatistics), %y", status);
-	  else
-	    auth_luid = stats.AuthenticationId;
 	}
 
       /* Retrieving current processes group list to be able to inherit
@@ -968,12 +960,10 @@ create_token (cygsid &usersid, user_groups &new_groups)
     }
 
   /* Create list of groups, the user is member in. */
-  int auth_pos;
   if (new_groups.issetgroups ())
-    get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups,
-			   auth_luid, auth_pos);
+    get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups);
   else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
-				    my_tok_gsids, auth_luid, auth_pos))
+				    my_tok_gsids))
     goto out;
 
   /* Primary group. */
@@ -991,8 +981,6 @@ create_token (cygsid &usersid, user_groups &new_groups)
 					    | SE_GROUP_ENABLED_BY_DEFAULT
 					    | SE_GROUP_ENABLED;
     }
-  if (auth_pos >= 0)
-    new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
 
   /* Retrieve list of privileges of that user.  Based on the usersid and
      the returned privileges, get_priv_list sets the mandatory_integrity_sid
@@ -1052,7 +1040,6 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
   LSA_OPERATIONAL_MODE sec_mode;
   NTSTATUS status, sub_status;
   ULONG package_id, size;
-  LUID auth_luid = SYSTEM_LUID;
   struct {
     LSA_STRING str;
     CHAR buf[16];
@@ -1115,12 +1102,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
   ts.SourceIdentifier.LowPart = 0x0103;
 
   /* Create list of groups, the user is member in. */
-  int auth_pos;
   if (new_groups.issetgroups ())
-    get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups, auth_luid,
-			   auth_pos);
+    get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups);
   else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
-				    NULL, auth_luid, auth_pos))
+				    NULL))
     goto out;
 
   tmp_gsids.debug_print ("tmp_gsids");
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 201bd25..c7c9f2e 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -52,6 +52,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:false,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:false,
+  has_broken_whoami:true,
 };
 
 wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -86,6 +87,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:false,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:false,
+  has_broken_whoami:true,
 };
 
 wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -120,6 +122,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:false,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:false,
+  has_broken_whoami:true,
 };
 
 wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -154,6 +157,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:true,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:false,
+  has_broken_whoami:true,
 };
 
 wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -188,6 +192,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:true,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:false,
+  has_broken_whoami:false,
 };
 
 wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -222,6 +227,7 @@ wincaps wincap_10 __attribute__((section (".cygwin_dll_common"), shared)) = {
   has_processor_groups:true,
   has_broken_prefetchvm:true,
   has_new_pebteb_region:false,
+  has_broken_whoami:false,
 };
 
 wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -256,6 +262,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) =
   has_processor_groups:true,
   has_broken_prefetchvm:false,
   has_new_pebteb_region:true,
+  has_broken_whoami:false,
 };
 
 wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 4508974..9e29d4f 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -45,6 +45,7 @@ struct wincaps
   unsigned has_processor_groups				: 1;
   unsigned has_broken_prefetchvm			: 1;
   unsigned has_new_pebteb_region			: 1;
+  unsigned has_broken_whoami				: 1;
 };
 
 class wincapc
@@ -104,6 +105,7 @@ public:
   bool	IMPLEMENT (has_processor_groups)
   bool	IMPLEMENT (has_broken_prefetchvm)
   bool	IMPLEMENT (has_new_pebteb_region)
+  bool	IMPLEMENT (has_broken_whoami)
 
 #undef IMPLEMENT
 };


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