From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 59819 invoked by alias); 18 Feb 2019 20:46:05 -0000 Mailing-List: contact cygwin-cvs-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cygwin-cvs-owner@cygwin.com Received: (qmail 59798 invoked by uid 9078); 18 Feb 2019 20:46:05 -0000 Date: Mon, 18 Feb 2019 20:46:00 -0000 Message-ID: <20190218204605.59797.qmail@sourceware.org> Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: re-enable create_token for older systems X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: a96d68c5bd88080406d4523236449cf43ecebf39 X-Git-Newrev: e53373bbdb3b8b6d497e7c388138e3ba22fda902 X-SW-Source: 2019-q1/txt/msg00169.txt.bz2 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=e53373bbdb3b8b6d497e7c388138e3ba22fda902 commit e53373bbdb3b8b6d497e7c388138e3ba22fda902 Author: Corinna Vinschen 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 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. +Older systems, like WOW64 under Windows 7 64 bit, don't support +S4U 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. + + + If all of the above fails, our process has insufficient privileges to switch the user context at all, so set(e)uid fails and returns -1, setting errno to EPERM.