get_username.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /*
  2. * Implementation of get_username() for Windows.
  3. */
  4. #include "putty.h"
  5. #ifndef SECURITY_WIN32
  6. #define SECURITY_WIN32
  7. #endif
  8. #include <security.h>
  9. char *get_username(void)
  10. {
  11. DWORD namelen;
  12. char *user;
  13. bool got_username = false;
  14. DECL_WINDOWS_FUNCTION(static, BOOLEAN, GetUserNameExA,
  15. (EXTENDED_NAME_FORMAT, LPSTR, PULONG));
  16. {
  17. static bool tried_usernameex = false;
  18. if (!tried_usernameex) {
  19. /* Not available on Win9x, so load dynamically */
  20. HMODULE secur32 = load_system32_dll("secur32.dll");
  21. /* If MIT Kerberos is installed, the following call to
  22. GET_WINDOWS_FUNCTION makes Windows implicitly load
  23. sspicli.dll WITHOUT proper path sanitizing, so better
  24. load it properly before */
  25. HMODULE sspicli = load_system32_dll("sspicli.dll");
  26. (void)sspicli; /* squash compiler warning about unused variable */
  27. GET_WINDOWS_FUNCTION(secur32, GetUserNameExA);
  28. tried_usernameex = true;
  29. }
  30. }
  31. if (p_GetUserNameExA) {
  32. /*
  33. * If available, use the principal -- this avoids the problem
  34. * that the local username is case-insensitive but Kerberos
  35. * usernames are case-sensitive.
  36. */
  37. /* Get the length */
  38. namelen = 0;
  39. (void) p_GetUserNameExA(NameUserPrincipal, NULL, &namelen);
  40. user = snewn(namelen, char);
  41. got_username = p_GetUserNameExA(NameUserPrincipal, user, &namelen);
  42. if (got_username) {
  43. char *p = strchr(user, '@');
  44. if (p) *p = 0;
  45. } else {
  46. sfree(user);
  47. }
  48. }
  49. if (!got_username) {
  50. /* Fall back to local user name */
  51. namelen = 0;
  52. if (!GetUserName(NULL, &namelen)) {
  53. /*
  54. * Apparently this doesn't work at least on Windows XP SP2.
  55. * Thus assume a maximum of 256. It will fail again if it
  56. * doesn't fit.
  57. */
  58. namelen = 256;
  59. }
  60. user = snewn(namelen, char);
  61. got_username = GetUserName(user, &namelen);
  62. if (!got_username) {
  63. sfree(user);
  64. }
  65. }
  66. return got_username ? user : NULL;
  67. }