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>
This commit is contained in:
Corinna Vinschen 2019-02-18 21:00:59 +01:00
parent a96d68c5bd
commit e53373bbdb
5 changed files with 36 additions and 29 deletions

View File

@ -18,3 +18,7 @@ Bug Fixes
- Fix an accidentally introduced O_TEXT handling of pipes inherited - Fix an accidentally introduced O_TEXT handling of pipes inherited
from native Windows processes. from native Windows processes.
Addresses: https://cygwin.com/ml/cygwin/2019-02/msg00246.html 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

View File

@ -488,7 +488,6 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
return false; return false;
} }
#if 0 && S4U_RUNS_FINE
static void static void
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps) 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; grp_list *= well_known_users_sid;
} }
} }
#endif
bool bool
get_server_groups (cygsidlist &grp_list, PSID usersid, 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 && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
&& get_logon_server (domain, server, DS_IS_FLAT_NAME)) && get_logon_server (domain, server, DS_IS_FLAT_NAME))
{ {
#if 0 && S4U_RUNS_FINE
if (check_account_disabled == CHK_DISABLED) if (check_account_disabled == CHK_DISABLED)
{ {
NET_API_STATUS napi_stat; NET_API_STATUS napi_stat;
@ -577,14 +574,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
return false; return false;
} }
} }
#endif
get_user_groups (server, grp_list, user, domain); get_user_groups (server, grp_list, user, domain);
get_user_local_groups (server, domain, grp_list, user); get_user_local_groups (server, domain, grp_list, user);
} }
return true; return true;
} }
#if 0 && S4U_RUNS_FINE
static bool static bool
get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid, get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
PTOKEN_GROUPS my_grps) PTOKEN_GROUPS my_grps)
@ -762,7 +757,6 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
} }
return privs; return privs;
} }
#endif
/* Accept a token if /* Accept a token if
- the requested usersid matches the TokenUser and - the requested usersid matches the TokenUser and
@ -906,7 +900,6 @@ account_restriction (NTSTATUS status)
return type; return type;
} }
#if 0 && S4U_RUNS_FINE
HANDLE HANDLE
create_token (cygsid &usersid, user_groups &new_groups) create_token (cygsid &usersid, user_groups &new_groups)
{ {
@ -1061,6 +1054,7 @@ out:
return primary_token; return primary_token;
} }
#if 0 && S4U_RUNS_FINE
HANDLE HANDLE
lsaauth (cygsid &usersid, user_groups &new_groups) 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; } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON;
HANDLE HANDLE
s4uauth (struct passwd *pw) s4uauth (struct passwd *pw, NTSTATUS &ret_status)
{ {
LSA_STRING name; LSA_STRING name;
HANDLE lsa_hdl = NULL; HANDLE lsa_hdl = NULL;
@ -1614,5 +1608,6 @@ out:
LsaFreeReturnBuffer (profile); LsaFreeReturnBuffer (profile);
pop_self_privilege (); pop_self_privilege ();
ret_status = status;
return token; return token;
} }

View File

@ -480,7 +480,7 @@ HANDLE lsaauth (cygsid &, user_groups &);
/* LSA private key storage authentication, same as when using service logons. */ /* LSA private key storage authentication, same as when using service logons. */
HANDLE lsaprivkeyauth (struct passwd *pw); HANDLE lsaprivkeyauth (struct passwd *pw);
/* Kerberos or MsV1 S4U logon. */ /* Kerberos or MsV1 S4U logon. */
HANDLE s4uauth (struct passwd *pw); HANDLE s4uauth (struct passwd *pw, NTSTATUS &ret_status);
/* Verify an existing token */ /* Verify an existing token */
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
/* Get groups of a user */ /* Get groups of a user */

View File

@ -3564,31 +3564,29 @@ seteuid32 (uid_t uid)
} }
if (!new_token) if (!new_token)
{ {
#if 1 NTSTATUS status;
debug_printf ("lsaprivkeyauth failed, try s4uauth."); debug_printf ("lsaprivkeyauth failed, try s4uauth.");
if (!(new_token = s4uauth (pw_new))) if (!(new_token = s4uauth (pw_new, status)))
{ {
debug_printf ("s4uauth failed, bail out"); if (status != STATUS_INVALID_PARAMETER)
cygheap->user.reimpersonate ();
return -1;
}
#else
debug_printf ("lsaprivkeyauth failed, try lsaauth.");
if (!(new_token = lsaauth (usersid, groups)))
{
debug_printf ("lsaauth failed, try s4uauth.");
if (!(new_token = s4uauth (pw_new)))
{ {
debug_printf ("s4uauth failed, try create_token."); debug_printf ("s4uauth failed, bail out");
if (!(new_token = create_token (usersid, groups))) cygheap->user.reimpersonate ();
{ return -1;
debug_printf ("create_token failed, bail out"); }
cygheap->user.reimpersonate (); /* If s4uauth fails with status code STATUS_INVALID_PARAMETER,
return -1; 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 */ /* Keep at most one internal token */

View File

@ -2574,6 +2574,16 @@ use the returned token.</para>
to create a token.</para> to create a token.</para>
</listitem> </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> <listitem>
<para>If all of the above fails, our process has insufficient privileges <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> to switch the user context at all, so <command>set(e)uid</command>