public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin] Cygwin: re-enable create_token for older systems
@ 2019-02-18 20:46 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2019-02-18 20:46 UTC (permalink / raw)
  To: cygwin-cvs

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

commit e53373bbdb3b8b6d497e7c388138e3ba22fda902
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Feb 18 21:00:59 2019 +0100

    Cygwin: re-enable create_token for older systems
    
    Under WOW64 on 64 bit Windows 7, MsV1_0S4ULogon appears to be
    unimplemented, probably under Vista as well.  Re-enable
    create_token method, to allow basic seteuid on W7 WOW64 and
    Vista as well.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/release/3.0.1 |  4 ++++
 winsup/cygwin/sec_auth.cc   | 11 +++--------
 winsup/cygwin/security.h    |  2 +-
 winsup/cygwin/syscalls.cc   | 38 ++++++++++++++++++--------------------
 winsup/doc/ntsec.xml        | 10 ++++++++++
 5 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1
index 8c88f3c..1894c5c 100644
--- a/winsup/cygwin/release/3.0.1
+++ b/winsup/cygwin/release/3.0.1
@@ -18,3 +18,7 @@ Bug Fixes
 - Fix an accidentally introduced O_TEXT handling of pipes inherited
   from native Windows processes.
   Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00246.html
+
+- Re-enable creating user token from scratch in seteuid to allow
+  user context switch on old systems not supporting MsV1_0S4ULogon.
+  Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00277.html
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 6588e67..316ae99 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -488,7 +488,6 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
   return false;
 }
 
-#if 0 && S4U_RUNS_FINE
 static void
 get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
 {
@@ -524,7 +523,6 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
       grp_list *= well_known_users_sid;
     }
 }
-#endif
 
 bool
 get_server_groups (cygsidlist &grp_list, PSID usersid,
@@ -558,7 +556,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
       && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
       && get_logon_server (domain, server, DS_IS_FLAT_NAME))
     {
-#if 0 && S4U_RUNS_FINE
       if (check_account_disabled == CHK_DISABLED)
 	{
 	  NET_API_STATUS napi_stat;
@@ -577,14 +574,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
 	      return false;
 	    }
 	}
-#endif
       get_user_groups (server, grp_list, user, domain);
       get_user_local_groups (server, domain, grp_list, user);
     }
   return true;
 }
 
-#if 0 && S4U_RUNS_FINE
 static bool
 get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
 			PTOKEN_GROUPS my_grps)
@@ -762,7 +757,6 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
     }
   return privs;
 }
-#endif
 
 /* Accept a token if
    - the requested usersid matches the TokenUser and
@@ -906,7 +900,6 @@ account_restriction (NTSTATUS status)
   return type;
 }
 
-#if 0 && S4U_RUNS_FINE
 HANDLE
 create_token (cygsid &usersid, user_groups &new_groups)
 {
@@ -1061,6 +1054,7 @@ out:
   return primary_token;
 }
 
+#if 0 && S4U_RUNS_FINE
 HANDLE
 lsaauth (cygsid &usersid, user_groups &new_groups)
 {
@@ -1434,7 +1428,7 @@ typedef struct _MSV1_0_S4U_LOGON
 } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON;
 
 HANDLE
-s4uauth (struct passwd *pw)
+s4uauth (struct passwd *pw, NTSTATUS &ret_status)
 {
   LSA_STRING name;
   HANDLE lsa_hdl = NULL;
@@ -1614,5 +1608,6 @@ out:
     LsaFreeReturnBuffer (profile);
 
   pop_self_privilege ();
+  ret_status = status;
   return token;
 }
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 70912b4..cabb91d 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -480,7 +480,7 @@ HANDLE lsaauth (cygsid &, user_groups &);
 /* LSA private key storage authentication, same as when using service logons. */
 HANDLE lsaprivkeyauth (struct passwd *pw);
 /* Kerberos or MsV1 S4U logon. */
-HANDLE s4uauth (struct passwd *pw);
+HANDLE s4uauth (struct passwd *pw, NTSTATUS &ret_status);
 /* Verify an existing token */
 bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
 /* Get groups of a user */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 387f4da..c3a9244 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -3564,31 +3564,29 @@ seteuid32 (uid_t uid)
 	}
       if (!new_token)
 	{
-#if 1
+	  NTSTATUS status;
+
 	  debug_printf ("lsaprivkeyauth failed, try s4uauth.");
-	  if (!(new_token = s4uauth (pw_new)))
-	    {
-	      debug_printf ("s4uauth failed, bail out");
-	      cygheap->user.reimpersonate ();
-	      return -1;
-	    }
-#else
-	  debug_printf ("lsaprivkeyauth failed, try lsaauth.");
-	  if (!(new_token = lsaauth (usersid, groups)))
+	  if (!(new_token = s4uauth (pw_new, status)))
 	    {
-	      debug_printf ("lsaauth failed, try s4uauth.");
-	      if (!(new_token = s4uauth (pw_new)))
+	      if (status != STATUS_INVALID_PARAMETER)
 		{
-		  debug_printf ("s4uauth failed, try create_token.");
-		  if (!(new_token = create_token (usersid, groups)))
-		    {
-		      debug_printf ("create_token failed, bail out");
-		      cygheap->user.reimpersonate ();
-		      return -1;
-		    }
+		  debug_printf ("s4uauth failed, bail out");
+		  cygheap->user.reimpersonate ();
+		  return -1;
+		}
+	      /* If s4uauth fails with status code STATUS_INVALID_PARAMETER,
+		 we're running on a system not implementing MsV1_0S4ULogon
+		 (Windows 7 WOW64, Vista?).  Fall back to create_token in
+		 this single case only. */
+	      debug_printf ("s4uauth failed, try create_token.");
+	      if (!(new_token = create_token (usersid, groups)))
+		{
+		  debug_printf ("create_token failed, bail out");
+		  cygheap->user.reimpersonate ();
+		  return -1;
 		}
 	    }
-#endif
 	}
 
       /* Keep at most one internal token */
diff --git a/winsup/doc/ntsec.xml b/winsup/doc/ntsec.xml
index e8419c5..5287845 100644
--- a/winsup/doc/ntsec.xml
+++ b/winsup/doc/ntsec.xml
@@ -2575,6 +2575,16 @@ to create a token.</para>
 </listitem>
 
 <listitem>
+<para>Older systems, like WOW64 under Windows 7 64 bit, don't support
+<literal>S4U</literal> authentication for local machine accounts.  On
+these systems Cygwin falls back to an old and otherwise deprecated
+method to create a user token from scratch.  The underlying system call
+is undocumented and has an unfortunate requirement: We have to create a
+special account with dangerous permissions to perform this action.
+Therefore this is only enabled on affected systems.</para>
+</listitem>
+
+<listitem>
 <para>If all of the above fails, our process has insufficient privileges
 to switch the user context at all, so <command>set(e)uid</command>
 fails and returns -1, setting errno to EPERM.</para>


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-02-18 20:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 20:46 [newlib-cygwin] Cygwin: re-enable create_token for older systems Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).