You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CurrentUser.cxx 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. // -=- Currentuser.cxx
  19. #ifdef HAVE_CONFIG_H
  20. #include <config.h>
  21. #endif
  22. #include <stdlib.h>
  23. #include <rfb/LogWriter.h>
  24. #include <rfb_win32/CurrentUser.h>
  25. #include <rfb_win32/Service.h>
  26. #include <lmcons.h>
  27. #include <wtsapi32.h>
  28. using namespace rfb;
  29. using namespace win32;
  30. static LogWriter vlog("CurrentUser");
  31. const char* shellIconClass = "Shell_TrayWnd";
  32. BOOL CALLBACK enumWindows(HWND hwnd, LPARAM lParam) {
  33. char className[16];
  34. if (GetClassName(hwnd, className, sizeof(className)) &&
  35. (strcmp(className, shellIconClass) == 0)) {
  36. vlog.debug("located tray icon window (%s)", className);
  37. DWORD processId = 0;
  38. GetWindowThreadProcessId(hwnd, &processId);
  39. if (!processId)
  40. return TRUE;
  41. Handle process = OpenProcess(MAXIMUM_ALLOWED, FALSE, processId);
  42. if (!process.h)
  43. return TRUE;
  44. if (!OpenProcessToken(process, MAXIMUM_ALLOWED, (HANDLE*)lParam))
  45. return TRUE;
  46. vlog.debug("obtained user token");
  47. return FALSE;
  48. }
  49. return TRUE;
  50. }
  51. BOOL CALLBACK enumDesktops(LPTSTR lpszDesktop, LPARAM lParam) {
  52. HDESK desktop = OpenDesktop(lpszDesktop, 0, FALSE, DESKTOP_ENUMERATE);
  53. vlog.debug("opening \"%s\"", lpszDesktop);
  54. if (!desktop) {
  55. vlog.info("desktop \"%s\" inaccessible", lpszDesktop);
  56. return TRUE;
  57. }
  58. BOOL result = EnumDesktopWindows(desktop, enumWindows, lParam);
  59. if (!CloseDesktop(desktop))
  60. vlog.info("unable to close desktop: %ld", GetLastError());
  61. return result;
  62. }
  63. CurrentUserToken::CurrentUserToken() {
  64. if (isServiceProcess()) {
  65. // Try to get the user token using the Terminal Services APIs
  66. WTSQueryUserToken(-1, &h);
  67. } else {
  68. // Try to open the security token for the User-Mode process
  69. if (!OpenProcessToken(GetCurrentProcess(), GENERIC_ALL, &h)) {
  70. DWORD err = GetLastError();
  71. if (err != ERROR_CALL_NOT_IMPLEMENTED)
  72. throw rdr::SystemException("OpenProcessToken failed", err);
  73. h = INVALID_HANDLE_VALUE;
  74. }
  75. }
  76. }
  77. ImpersonateCurrentUser::ImpersonateCurrentUser() {
  78. RegCloseKey(HKEY_CURRENT_USER);
  79. if (!isServiceProcess())
  80. return;
  81. if (!token.canImpersonate())
  82. throw rdr::Exception("Cannot impersonate unsafe or null token");
  83. if (!ImpersonateLoggedOnUser(token)) {
  84. DWORD err = GetLastError();
  85. if (err != ERROR_CALL_NOT_IMPLEMENTED)
  86. throw rdr::SystemException("Failed to impersonate user", GetLastError());
  87. }
  88. }
  89. ImpersonateCurrentUser::~ImpersonateCurrentUser() {
  90. if (!RevertToSelf()) {
  91. DWORD err = GetLastError();
  92. if (err != ERROR_CALL_NOT_IMPLEMENTED)
  93. exit(err);
  94. }
  95. RegCloseKey(HKEY_CURRENT_USER);
  96. }
  97. UserName::UserName() {
  98. char buf[UNLEN+1];
  99. DWORD len = UNLEN+1;
  100. if (!GetUserName(buf, &len))
  101. throw rdr::SystemException("GetUserName failed", GetLastError());
  102. assign(buf);
  103. }
  104. UserSID::UserSID() {
  105. CurrentUserToken token;
  106. if (!token.canImpersonate())
  107. return;
  108. setSID(Sid::FromToken(token.h));
  109. }