From 491a69769cb9db97e6566679b6ac0887bdda3292 Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 19 Nov 2010 12:38:01 +0000 Subject: Updated to revision 9025 of putty --- tools/plink/winmisc.c | 86 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 9 deletions(-) (limited to 'tools/plink/winmisc.c') diff --git a/tools/plink/winmisc.c b/tools/plink/winmisc.c index 8ffbe77a1..e70e77efa 100644 --- a/tools/plink/winmisc.c +++ b/tools/plink/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; -- cgit v1.2.3