Leaked source code of windows server 2003
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.

198 lines
6.4 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CImpersonateUser.cpp
  7. //
  8. // Description:
  9. // Contains the definition of the CImpersonateUser class.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 14-JU-2001
  13. // Vij Vasu (Vvasu) 16-MAY-2000
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. //////////////////////////////////////////////////////////////////////////////
  17. // Include Files
  18. //////////////////////////////////////////////////////////////////////////////
  19. // The precompiled header.
  20. #include "Pch.h"
  21. // The header for this file
  22. #include "CImpersonateUser.h"
  23. //////////////////////////////////////////////////////////////////////////////
  24. //++
  25. //
  26. // CImpersonateUser::CImpersonateUser
  27. //
  28. // Description:
  29. // Constructor of the CImpersonateUser class. Begins impersonating the
  30. // user specified by the argument.
  31. //
  32. // Arguments:
  33. // hUserToken
  34. // Handle to the user account token to impersonate
  35. //
  36. // Return Value:
  37. // None.
  38. //
  39. // Exceptions Thrown:
  40. // CRuntimeError
  41. // If any of the APIs fail.
  42. //
  43. //--
  44. //////////////////////////////////////////////////////////////////////////////
  45. CImpersonateUser::CImpersonateUser( HANDLE hUserToken )
  46. : m_hThreadToken( NULL )
  47. , m_fWasImpersonating( false )
  48. {
  49. TraceFunc1( "hUserToken = %p", hUserToken );
  50. DWORD sc = ERROR_SUCCESS;
  51. do
  52. {
  53. // Check if this thread is already impersonating a client.
  54. {
  55. if ( OpenThreadToken(
  56. GetCurrentThread()
  57. , TOKEN_ALL_ACCESS
  58. , FALSE
  59. , &m_hThreadToken
  60. )
  61. == FALSE
  62. )
  63. {
  64. sc = GetLastError();
  65. if ( sc == ERROR_NO_TOKEN )
  66. {
  67. // There is no thread token, so we are not impersonating - this is ok.
  68. TraceFlow( "This thread is not impersonating anyone." );
  69. m_fWasImpersonating = false;
  70. sc = ERROR_SUCCESS;
  71. } // if: there is no thread token
  72. else
  73. {
  74. TW32( sc );
  75. LogMsg( "[BC] Error %#08x occurred opening the thread token..", sc );
  76. break;
  77. } // else: something really went wrong
  78. } // if: OpenThreadToken() failed
  79. else
  80. {
  81. TOKEN_TYPE ttTokenType;
  82. DWORD dwReturnLength;
  83. if ( GetTokenInformation(
  84. m_hThreadToken
  85. , TokenType
  86. , &ttTokenType
  87. , sizeof( ttTokenType )
  88. , &dwReturnLength
  89. )
  90. == FALSE
  91. )
  92. {
  93. sc = TW32( GetLastError() );
  94. LogMsg( "[BC] Error %#08x getting thread token information.", sc );
  95. break;
  96. } // if: GetTokenInformation() failed
  97. else
  98. {
  99. Assert( dwReturnLength == sizeof( ttTokenType ) );
  100. m_fWasImpersonating = ( ttTokenType == TokenImpersonation );
  101. TraceFlow1( "Is this thread impersonating anyone? %d ( 0 = No ).", m_fWasImpersonating );
  102. } // else: GetTokenInformation() succeeded
  103. } // else: OpenThreadToken() succeeded
  104. }
  105. // Try to impersonate the user.
  106. if ( ImpersonateLoggedOnUser( hUserToken ) == FALSE )
  107. {
  108. sc = TW32( GetLastError() );
  109. LogMsg( "[BC] Error %#08x occurred impersonating the logged on user.", sc );
  110. break;
  111. } // if: ImpersonateLoggedOnUser() failed
  112. TraceFlow( "Impersonation succeeded." );
  113. }
  114. while( false ); // dummy do-while loop to avoid gotos.
  115. if ( sc != ERROR_SUCCESS )
  116. {
  117. LogMsg( "[BC] Error %#08x occurred trying to impersonate a user. Throwing an exception.", sc );
  118. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( sc ), IDS_ERROR_IMPERSONATE_USER );
  119. } // if:something went wrong
  120. TraceFuncExit();
  121. } //*** CImpersonateUser::CImpersonateUser
  122. //////////////////////////////////////////////////////////////////////////////
  123. //++
  124. //
  125. // CImpersonateUser::~CImpersonateUser
  126. //
  127. // Description:
  128. // Destructor of the CImpersonateUser class. Reverts to the original token.
  129. //
  130. // Arguments:
  131. // None.
  132. //
  133. // Return Value:
  134. // None.
  135. //
  136. // Exceptions Thrown:
  137. // None.
  138. //
  139. //--
  140. //////////////////////////////////////////////////////////////////////////////
  141. CImpersonateUser::~CImpersonateUser( void ) throw()
  142. {
  143. TraceFunc( "" );
  144. if ( m_fWasImpersonating )
  145. {
  146. // Try to revert to the previous impersonation.
  147. if ( ImpersonateLoggedOnUser( m_hThreadToken ) == FALSE )
  148. {
  149. // Something failed - nothing much we can do here
  150. DWORD sc = TW32( GetLastError() );
  151. LogMsg( "[BC] !!! WARNING !!! Error %#08x occurred trying to revert to previous impersonation. Cannot throw exception from destructor. Application may not run properly.", sc );
  152. } // if: ImpersonateLoggedOnUser() failed
  153. else
  154. {
  155. TraceFlow( "Successfully reverted to previous impersonation." );
  156. } // else: ImpersonateLoggedOnUser() succeeded
  157. } // if: we were impersonating someone when we started
  158. else
  159. {
  160. // Try to revert to self.
  161. if ( RevertToSelf() == FALSE )
  162. {
  163. DWORD sc = TW32( GetLastError() );
  164. LogMsg( "[BC] !!! WARNING !!! Error %#08x occurred trying to revert to self. Cannot throw exception from destructor. Application may not run properly.", sc );
  165. } // if: RevertToSelf() failed
  166. else
  167. {
  168. TraceFlow( "Successfully reverted to self." );
  169. } // else: RevertToSelf() succeeded
  170. } // else: we weren't impersonating anyone to begin with
  171. TraceFuncExit();
  172. } //*** CImpersonateUser::~CImpersonateUser