aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-02-18 21:00:59 +0100
committerCorinna Vinschen <corinna@vinschen.de>2019-02-18 21:00:59 +0100
commite53373bbdb3b8b6d497e7c388138e3ba22fda902 (patch)
tree0652d365e530cdc72e631e1811645f605921ef7b
parenta96d68c5bd88080406d4523236449cf43ecebf39 (diff)
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>
-rw-r--r--winsup/cygwin/release/3.0.14
-rw-r--r--winsup/cygwin/sec_auth.cc11
-rw-r--r--winsup/cygwin/security.h2
-rw-r--r--winsup/cygwin/syscalls.cc38
-rw-r--r--winsup/doc/ntsec.xml10
5 files changed, 36 insertions, 29 deletions
diff --git a/winsup/cygwin/release/3.0.1 b/winsup/cygwin/release/3.0.1
index 8c88f3c2a..1894c5c00 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 6588e6781..316ae99d9 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 70912b4fc..cabb91d25 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 387f4da32..c3a92445e 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 e8419c5bc..528784568 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>