diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 73367dfd8..056fac7dc 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -642,6 +642,7 @@ LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32) LoadDLLfunc (CoTaskMemFree, 4, ole32) +LoadDLLfunc (LsaConnectUntrusted, 4, secur32) LoadDLLfunc (LsaDeregisterLogonProcess, 4, secur32) LoadDLLfunc (LsaFreeReturnBuffer, 4, secur32) LoadDLLfunc (LsaLogonUser, 56, secur32) diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc index 3a08671a5..54182dd6c 100644 --- a/winsup/cygwin/sec_auth.cc +++ b/winsup/cygwin/sec_auth.cc @@ -22,7 +22,6 @@ details. */ #include "tls_pbuf.h" #include #include -#include #include #define SECURITY_WIN32 #include @@ -1421,7 +1420,7 @@ out: */ /* In Mingw-w64, MsV1_0S4ULogon and MSV1_0_S4U_LOGON are only defined - in ddk/ntifs.h. We can't inlcude this. */ + in ddk/ntifs.h. We can't include this. */ #define MsV1_0S4ULogon ((MSV1_0_LOGON_SUBMIT_TYPE) 12) @@ -1433,15 +1432,18 @@ typedef struct _MSV1_0_S4U_LOGON UNICODE_STRING DomainName; } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON; +/* Missing in Mingw-w64 */ +#define KERB_S4U_LOGON_FLAG_IDENTITY 0x08 + +/* If logon is true we need an impersonation token. Otherwise we just + need an identification token, e. g. to fetch the group list. */ HANDLE -s4uauth (struct passwd *pw, NTSTATUS &ret_status) +s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status) { LSA_STRING name; HANDLE lsa_hdl = NULL; LSA_OPERATIONAL_MODE sec_mode; NTSTATUS status, sub_status; - WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; - WCHAR user[UNLEN + 1]; bool try_kerb_auth; ULONG package_id, size; struct { @@ -1460,19 +1462,23 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status) push_self_privilege (SE_TCB_PRIVILEGE, true); - /* Register as logon process. */ - RtlInitAnsiString (&name, "Cygwin"); - status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + if (logon) + { + /* Register as logon process. */ + RtlInitAnsiString (&name, "Cygwin"); + status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode); + } + else + status = LsaConnectUntrusted (&lsa_hdl); if (status != STATUS_SUCCESS) { - debug_printf ("LsaRegisterLogonProcess: %y", status); + debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess" + : "LsaConnectUntrusted", status); __seterrno_from_nt_status (status); goto out; } - /* Fetch user and domain name and check if this is a domain user. - If so, try Kerberos first. */ - extract_nt_dom_user (pw, domain, user); + /* Check if this is a domain user. If so, try Kerberos first. */ try_kerb_auth = cygheap->dom.member_machine () && wcscasecmp (domain, cygheap->dom.account_flat_name ()); /* Create origin. */ @@ -1523,7 +1529,7 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status) RtlSecureZeroMemory (authinf, authinf_size); s4u_logon = (KERB_S4U_LOGON *) authinf; s4u_logon->MessageType = KerbS4ULogon; - s4u_logon->Flags = 0; + s4u_logon->Flags = logon ? 0 : KERB_S4U_LOGON_FLAG_IDENTITY; /* Append user to login info */ RtlInitEmptyUnicodeString (&s4u_logon->ClientUpn, (PWCHAR) (s4u_logon + 1), @@ -1615,7 +1621,7 @@ out: if (profile) LsaFreeReturnBuffer (profile); - if (token) + if (token && logon) { /* Convert to primary token. Strictly speaking this is only required on Vista/2008. CreateProcessAsUser also takes diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index cabb91d25..483a527e7 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, NTSTATUS &ret_status); +HANDLE s4uauth (bool logon, PCWSTR domain, PCWSTR user, 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 c3a92445e..f4e8bcf2c 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -37,6 +37,7 @@ details. */ #include #include #include +#include #include "ntdll.h" #undef fstat @@ -3565,9 +3566,12 @@ seteuid32 (uid_t uid) if (!new_token) { NTSTATUS status; + WCHAR domain[MAX_DOMAIN_NAME_LEN + 1]; + WCHAR user[UNLEN + 1]; debug_printf ("lsaprivkeyauth failed, try s4uauth."); - if (!(new_token = s4uauth (pw_new, status))) + extract_nt_dom_user (pw_new, domain, user); + if (!(new_token = s4uauth (true, domain, user, status))) { if (status != STATUS_INVALID_PARAMETER) {