diff --git a/contrib/win32/openssh/README.txt b/contrib/win32/openssh/README.txt index 18eb6bed0649..675ede9a0b7f 100644 --- a/contrib/win32/openssh/README.txt +++ b/contrib/win32/openssh/README.txt @@ -30,8 +30,7 @@ Before building OpenSSH for Windows, install the following: same install / v143 toolset automatically. 2. Git for Windows. - The build script expects git.exe to be on PATH (it will add - "%ProgramFiles%\Git\cmd" to the machine PATH if missing). + The build script expects git.exe to be on PATH. 3. vcpkg (one-time bootstrap). Dependencies (LibreSSL, libfido2, zlib, libcbor) are managed via a diff --git a/contrib/win32/openssh/sshd-auth.vcxproj b/contrib/win32/openssh/sshd-auth.vcxproj index fd3a28e06214..1d9e4a6c0be3 100644 --- a/contrib/win32/openssh/sshd-auth.vcxproj +++ b/contrib/win32/openssh/sshd-auth.vcxproj @@ -1,6 +1,20 @@ + + + $(AdditionalDependentLibs);delayimp.lib + Debug @@ -112,6 +126,11 @@ true + + + /DELAYLOAD:user32.dll %(AdditionalOptions) + + diff --git a/contrib/win32/win32compat/win32_usertoken_utils.c b/contrib/win32/win32compat/win32_usertoken_utils.c index 2b8ede0d43c8..57e517f6e665 100644 --- a/contrib/win32/win32compat/win32_usertoken_utils.c +++ b/contrib/win32/win32compat/win32_usertoken_utils.c @@ -94,6 +94,24 @@ EnablePrivilege(const char *privName, int enabled) return; } +static BOOL +is_domain_joined_machine(void) +{ + BOOL result = FALSE; + LPWSTR name = NULL; + NETSETUP_JOIN_STATUS s = NetSetupUnknownStatus; + DWORD api_res = NetGetJoinInformation(NULL, &name, &s); + if (api_res == NERR_Success) { + result = s == NetSetupDomainName; + NetApiBufferFree(name); + name = NULL; + } else { + debug("%s: NetGetJoinInformation() failed. Error %d.", __FUNCTION__, api_res); + } + debug("%s: NetGetJoinInformation(). Join result %d", __FUNCTION__, result); + return result; +} + HANDLE generate_s4u_user_token(wchar_t* user_cpn, int impersonation) { HANDLE lsa_handle = NULL, token = NULL; @@ -112,7 +130,8 @@ generate_s4u_user_token(wchar_t* user_cpn, int impersonation) { * so only the only two formats are a NetBiosDomain\SamAccountName which is * a domain account or just SamAccountName in which is a local account */ BOOL domain_user = wcschr(user_cpn, L'\\') != NULL; - + BOOL use_kerberos = domain_user && is_domain_joined_machine(); + /* initialize connection to local security provider */ if (impersonation) { @@ -132,11 +151,11 @@ generate_s4u_user_token(wchar_t* user_cpn, int impersonation) { goto done; } - InitLsaString(&auth_package_name, (domain_user) ? MICROSOFT_KERBEROS_NAME_A : MSV1_0_PACKAGE_NAME); + InitLsaString(&auth_package_name, use_kerberos ? MICROSOFT_KERBEROS_NAME_A : MSV1_0_PACKAGE_NAME); if (ret = LsaLookupAuthenticationPackage(lsa_handle, &auth_package_name, &auth_package_id) != STATUS_SUCCESS) goto done; - if (domain_user) { + if (use_kerberos) { /* lookup the user principal name for the account */ WCHAR domain_upn[MAX_UPN_LEN + 1]; @@ -168,6 +187,11 @@ generate_s4u_user_token(wchar_t* user_cpn, int impersonation) { } else { + /* if a domain prefix slipped through (non-domain-joined host. e.g. winpe is backed with such domain), + point past it without mutating the caller's buffer */ + wchar_t *backslash = wcschr(user_cpn, L'\\'); + if (backslash != NULL) + user_cpn = backslash + 1; MSV1_0_S4U_LOGON *s4u_logon; logon_info_size = sizeof(MSV1_0_S4U_LOGON); @@ -432,7 +456,7 @@ load_user_profile(HANDLE user_token, char* user) EnablePrivilege("SeBackupPrivilege", 1); EnablePrivilege("SeRestorePrivilege", 1); if (LoadUserProfileW(user_token, &profileInfo) == FALSE) { - debug3("%s: LoadUserProfileW() failed for user %S with error %d.", __FUNCTION__, GetLastError()); + debug3("%s: LoadUserProfileW() failed for user %S with error %d.", __FUNCTION__, user_name, GetLastError()); } EnablePrivilege("SeBackupPrivilege", 0); EnablePrivilege("SeRestorePrivilege", 0);