X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/8def70c3ec6f81f95673c0de67a75b5a6b2e9e1c..783c82b3c5bb0f07deae79e012a864a54bec8749:/windows/winmisc.c diff --git a/windows/winmisc.c b/windows/winmisc.c index e5143d92..d05a07ab 100644 --- a/windows/winmisc.c +++ b/windows/winmisc.c @@ -5,6 +5,7 @@ #include #include #include "putty.h" +#include OSVERSIONINFO osVersion; @@ -40,21 +41,61 @@ char *get_username(void) { DWORD namelen; char *user; + int got_username = FALSE; + DECL_WINDOWS_FUNCTION(static, BOOLEAN, GetUserNameExA, + (EXTENDED_NAME_FORMAT, LPSTR, PULONG)); + + { + static int tried_usernameex = FALSE; + if (!tried_usernameex) { + /* Not available on Win9x, so load dynamically */ + HMODULE secur32 = load_system32_dll("secur32.dll"); + GET_WINDOWS_FUNCTION(secur32, GetUserNameExA); + tried_usernameex = TRUE; + } + } - namelen = 0; - if (GetUserName(NULL, &namelen) == FALSE) { + if (p_GetUserNameExA) { /* - * Apparently this doesn't work at least on Windows XP SP2. - * Thus assume a maximum of 256. It will fail again if it - * doesn't fit. + * If available, use the principal -- this avoids the problem + * that the local username is case-insensitive but Kerberos + * usernames are case-sensitive. */ - namelen = 256; + + /* Get the length */ + namelen = 0; + (void) p_GetUserNameExA(NameUserPrincipal, NULL, &namelen); + + user = snewn(namelen, char); + got_username = p_GetUserNameExA(NameUserPrincipal, user, &namelen); + if (got_username) { + char *p = strchr(user, '@'); + if (p) *p = 0; + } else { + sfree(user); + } } - user = snewn(namelen, char); - GetUserName(user, &namelen); + if (!got_username) { + /* Fall back to local user name */ + namelen = 0; + if (GetUserName(NULL, &namelen) == FALSE) { + /* + * Apparently this doesn't work at least on Windows XP SP2. + * Thus assume a maximum of 256. It will fail again if it + * doesn't fit. + */ + namelen = 256; + } + + user = snewn(namelen, char); + got_username = GetUserName(user, &namelen); + if (!got_username) { + sfree(user); + } + } - return user; + return got_username ? user : NULL; } BOOL init_winver(void) @@ -64,6 +105,33 @@ BOOL init_winver(void) return GetVersionEx ( (OSVERSIONINFO *) &osVersion); } +HMODULE load_system32_dll(const char *libname) +{ + /* + * Wrapper function to load a DLL out of c:\windows\system32 + * without going through the full DLL search path. (Hence no + * attack is possible by placing a substitute DLL earlier on that + * path.) + */ + static char *sysdir = NULL; + char *fullpath; + HMODULE ret; + + if (!sysdir) { + int size = 0, len; + do { + size = 3*size/2 + 512; + sysdir = sresize(sysdir, size, char); + len = GetSystemDirectory(sysdir, size); + } while (len >= size); + } + + fullpath = dupcat(sysdir, "\\", libname, NULL); + ret = LoadLibrary(fullpath); + sfree(fullpath); + return ret; +} + #ifdef DEBUG static FILE *debug_fp = NULL; static HANDLE debug_hdl = INVALID_HANDLE_VALUE;