From 4c26bb506b3c12443171551b103a81b038d25334 Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 24 Mar 2010 20:12:25 +0000 Subject: [PATCH] When looking for a local username on Windows, if we can get hold of the NameUserPrincipal, use that; this avoids an issue with SSPI/GSSAPI where the user logged in to the local machine with a different case of username to the (case-sensitive) Kerberos username. Falls back to GetUserName as before if that doesn't work (for machines not on a domain, and Win9x). Based on a patch by SebastianUnger. git-svn-id: svn://svn.tartarus.org/sgt/putty@8909 cda61777-01e9-0310-a592-d414129be87e --- config.c | 3 ++- settings.c | 10 +++++++--- windows/winmisc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 59 insertions(+), 13 deletions(-) diff --git a/config.c b/config.c index f44b7603..464a2415 100644 --- a/config.c +++ b/config.c @@ -1765,7 +1765,8 @@ void setup_config_box(struct controlbox *b, int midsession, /* We assume the local username is sufficiently stable * to include on the dialog box. */ char *user = get_username(); - char *userlabel = dupprintf("Use system username (%s)", user); + char *userlabel = dupprintf("Use system username (%s)", + user ? user : ""); sfree(user); ctrl_radiobuttons(s, "When username is not specified:", 'n', 4, HELPCTX(connection_username_from_env), diff --git a/settings.c b/settings.c index 52538f62..9985e2d1 100644 --- a/settings.c +++ b/settings.c @@ -84,9 +84,13 @@ int get_remote_username(Config *cfg, char *user, size_t len) if (cfg->username_from_env) { /* Use local username. */ char *luser = get_username(); - strncpy(user, luser, len); - user[len-1] = '\0'; - sfree(luser); + if (luser) { + strncpy(user, luser, len); + user[len-1] = '\0'; + sfree(luser); + } else { + *user = '\0'; + } } else { *user = '\0'; } diff --git a/windows/winmisc.c b/windows/winmisc.c index e5143d92..c7ac8357 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 = LoadLibrary("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) -- 2.11.0