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.

199 lines
5.0 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved /
  3. /*****************************************************************************/
  4. /*
  5. * CTokenPrivilege.cpp - implementation file for CTokenPrivilege class.
  6. *
  7. * Created: 12-14-1997 by Sanjeev Surati
  8. * (based on classes from Windows NT Security by Nik Okuntseff)
  9. */
  10. #include "precomp.h"
  11. #include "TokenPrivilege.h"
  12. ///////////////////////////////////////////////////////////////////
  13. //
  14. // Function: CTokenPrivilege::CTokenPrivilege
  15. //
  16. // Class constructor.
  17. //
  18. // Inputs:
  19. // LPCTSTR pszPrivilegeName - The name of the privilege
  20. // this instance will be responsible for.
  21. // HANDLE hAccessToken - User supplied access token.
  22. //
  23. // Outputs:
  24. // None.
  25. //
  26. // Returns:
  27. // None.
  28. //
  29. // Comments:
  30. //
  31. // If the user does NOT supply an access token, we try to open
  32. // a thread token, and if that fails, then the process token.
  33. //
  34. ///////////////////////////////////////////////////////////////////
  35. CTokenPrivilege::CTokenPrivilege( LPCTSTR pszPrivilegeName, HANDLE hAccessToken /*=INVALID_HANDLE_VALUE*/, LPCTSTR pszSystemName /*=NULL*/ )
  36. : m_strPrivilegeName( pszPrivilegeName ),
  37. m_strSystemName( pszSystemName ),
  38. m_hAccessToken( NULL ),
  39. m_fClearToken( FALSE )
  40. {
  41. // If we weren't passed in a valid handle, open the current process token, acknowledging
  42. // that if we do so, we must also clear the token if we opened it.
  43. DWORD dwError = ERROR_SUCCESS;
  44. if ( INVALID_HANDLE_VALUE == hAccessToken )
  45. {
  46. // First try to get a thread token. If this fails because there is no token,
  47. // then grab the process token.
  48. if ( OpenThreadToken( GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &m_hAccessToken ) )
  49. {
  50. m_fClearToken = TRUE;
  51. }
  52. else
  53. {
  54. if ( ( dwError = ::GetLastError() ) == ERROR_NO_TOKEN )
  55. {
  56. if ( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &m_hAccessToken ) )
  57. {
  58. m_fClearToken = TRUE;
  59. }
  60. }
  61. }
  62. }
  63. else
  64. {
  65. m_hAccessToken = hAccessToken;
  66. }
  67. // Now, get the LUID for the privilege from the local system
  68. ZeroMemory( &m_luid, sizeof(m_luid) );
  69. {
  70. LookupPrivilegeValue( pszSystemName, pszPrivilegeName, &m_luid );
  71. }
  72. }
  73. ///////////////////////////////////////////////////////////////////
  74. //
  75. // Function: CTokenPrivilege::~CTokenPrivilege
  76. //
  77. // Class destructor.
  78. //
  79. // Inputs:
  80. // None.
  81. //
  82. // Outputs:
  83. // None.
  84. //
  85. // Returns:
  86. // None.
  87. //
  88. // Comments:
  89. //
  90. // Cleans up our token only if we Opened it ourselves.
  91. //
  92. ///////////////////////////////////////////////////////////////////
  93. CTokenPrivilege::~CTokenPrivilege( void )
  94. {
  95. if ( m_fClearToken )
  96. {
  97. CloseHandle( m_hAccessToken );
  98. }
  99. }
  100. ///////////////////////////////////////////////////////////////////
  101. //
  102. // Function: CTokenPrivilege::GetPrivilegeDisplayName
  103. //
  104. // Returns a Human readable name for the the token privilege the
  105. // class is handling.
  106. //
  107. // Inputs:
  108. // None.
  109. //
  110. // Outputs:
  111. // CHString& strDisplayName - Display name.
  112. // LPDWORD pdwLanguageId - Language Id of the
  113. // display name.
  114. //
  115. // Returns:
  116. // DWORD ERROR_SUCCESS if successful.
  117. //
  118. // Comments:
  119. //
  120. ///////////////////////////////////////////////////////////////////
  121. DWORD CTokenPrivilege::GetPrivilegeDisplayName( CHString& strDisplayName, LPDWORD pdwLanguageId )
  122. {
  123. DWORD dwError = ERROR_SUCCESS;
  124. DWORD dwDisplayNameSize = 0;
  125. // First, find out how big the buffer in strDisplayName needs to be
  126. LookupPrivilegeDisplayNameW( ( m_strSystemName.IsEmpty() ? NULL : (LPCWSTR) m_strSystemName ),
  127. m_strPrivilegeName,
  128. NULL,
  129. &dwDisplayNameSize,
  130. pdwLanguageId );
  131. {
  132. if ( !LookupPrivilegeDisplayNameW( ( m_strSystemName.IsEmpty() ? NULL : (LPCWSTR) m_strSystemName ),
  133. m_strPrivilegeName,
  134. strDisplayName.GetBuffer( dwDisplayNameSize + 1 ),
  135. &dwDisplayNameSize,
  136. pdwLanguageId ) )
  137. {
  138. dwError = ::GetLastError();
  139. }
  140. }
  141. strDisplayName.ReleaseBuffer();
  142. return dwError;
  143. }
  144. ///////////////////////////////////////////////////////////////////
  145. //
  146. // Function: CTokenPrivilege::Enable
  147. //
  148. // Attempts to enable/disable the privilege we are managing, in
  149. // our token data member.
  150. //
  151. // Inputs:
  152. // BOOL fEnable - Enable/Disable flag.
  153. //
  154. // Outputs:
  155. // None.
  156. //
  157. // Returns:
  158. // DWORD ERROR_SUCCESS if successful.
  159. //
  160. // Comments:
  161. //
  162. ///////////////////////////////////////////////////////////////////
  163. DWORD CTokenPrivilege::Enable( bool fEnable/*=TRUE*/ )
  164. {
  165. DWORD dwError = ERROR_SUCCESS;
  166. TOKEN_PRIVILEGES tokenPrivileges;
  167. tokenPrivileges.PrivilegeCount = 1;
  168. tokenPrivileges.Privileges[0].Luid = m_luid;
  169. tokenPrivileges.Privileges[0].Attributes = ( fEnable ? SE_PRIVILEGE_ENABLED : 0 );
  170. {
  171. AdjustTokenPrivileges(m_hAccessToken, FALSE, &tokenPrivileges, 0, NULL, NULL);
  172. dwError = ::GetLastError();
  173. }
  174. return dwError;
  175. }