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.

211 lines
5.6 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. priv.cxx
  6. Abstract:
  7. This file provides useful accssors and mutators.
  8. Author:
  9. Larry Zhu (LZhu) January 14, 2002 Created
  10. Environment:
  11. User Mode -Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.hxx"
  15. #pragma hdrstop
  16. #include "priv.hxx"
  17. TPrivilege::TPrivilege(
  18. IN ULONG Privilege,
  19. IN BOOLEAN bEnable
  20. ) : m_Privilege(Privilege),
  21. m_bEnable(bEnable),
  22. m_hToken(NULL),
  23. m_Status(STATUS_UNSUCCESSFUL)
  24. {
  25. m_Status DBGCHK = Initialize();
  26. }
  27. TPrivilege::~TPrivilege(
  28. VOID
  29. )
  30. {
  31. if (m_hToken)
  32. {
  33. TNtStatus Status;
  34. BOOLEAN bWasEnabled = FALSE;
  35. LUID LuidPrivilege = {0};
  36. PTOKEN_PRIVILEGES pNewPrivileges = NULL;
  37. PTOKEN_PRIVILEGES pOldPrivileges = NULL;
  38. ULONG cbReturnLength = 0;
  39. UCHAR Buffer1[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
  40. UCHAR Buffer2[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
  41. pNewPrivileges = (PTOKEN_PRIVILEGES)Buffer1;
  42. pOldPrivileges = (PTOKEN_PRIVILEGES)Buffer2;
  43. LuidPrivilege = RtlConvertUlongToLuid(m_Privilege);
  44. pNewPrivileges->PrivilegeCount = 1;
  45. pNewPrivileges->Privileges[0].Luid = LuidPrivilege;
  46. pNewPrivileges->Privileges[0].Attributes = !m_bEnable ? SE_PRIVILEGE_ENABLED : 0;
  47. Status DBGCHK = NtAdjustPrivilegesToken(
  48. m_hToken, // TokenHandle
  49. FALSE, // DisableAllPrivileges
  50. pNewPrivileges, // NewPrivileges
  51. sizeof(Buffer1), // BufferLength
  52. pOldPrivileges, // PreviousState (OPTIONAL)
  53. &cbReturnLength // ReturnLength
  54. );
  55. if (NT_SUCCESS(Status))
  56. {
  57. if (pOldPrivileges->PrivilegeCount == 0)
  58. {
  59. bWasEnabled = m_bEnable;
  60. }
  61. else
  62. {
  63. bWasEnabled = (pOldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? TRUE : FALSE;
  64. }
  65. SspiPrint(SSPI_LOG, TEXT("TPrivilege::~TPrivilege %s privilege %#x for token %p (WasEnable? %#x)\n"),
  66. !m_bEnable ? TEXT("enables") : TEXT("disables"),
  67. m_Privilege,
  68. m_hToken,
  69. bWasEnabled);
  70. }
  71. NtClose(m_hToken);
  72. }
  73. }
  74. NTSTATUS
  75. TPrivilege::Validate(
  76. VOID
  77. ) const
  78. {
  79. return m_Status;
  80. }
  81. /******************************************************************************
  82. Private Methods
  83. ******************************************************************************/
  84. NTSTATUS
  85. TPrivilege::Initialize(
  86. VOID
  87. )
  88. {
  89. TNtStatus Status = STATUS_UNSUCCESSFUL;
  90. LUID LuidPrivilege = {0};
  91. PTOKEN_PRIVILEGES pNewPrivileges = NULL;
  92. PTOKEN_PRIVILEGES pOldPrivileges = NULL;
  93. HANDLE hToken = NULL;
  94. ULONG cbReturnLength = 0;
  95. BOOLEAN bWasEnabled = FALSE;
  96. BOOLEAN bIsImpersonation = TRUE;
  97. UCHAR Buffer1[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
  98. UCHAR Buffer2[sizeof(TOKEN_PRIVILEGES) + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))] = {0};
  99. pNewPrivileges = (PTOKEN_PRIVILEGES) Buffer1;
  100. pOldPrivileges = (PTOKEN_PRIVILEGES) Buffer2;
  101. DBGCFG1(Status, STATUS_NO_TOKEN);
  102. Status DBGCHK = NtOpenThreadToken(
  103. NtCurrentThread(),
  104. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  105. FALSE,
  106. &hToken
  107. );
  108. if (STATUS_NO_TOKEN == (NTSTATUS) Status)
  109. {
  110. bIsImpersonation = FALSE;
  111. Status DBGCHK = NtOpenProcessToken(
  112. NtCurrentProcess(),
  113. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  114. &hToken
  115. );
  116. }
  117. if (NT_SUCCESS(Status))
  118. {
  119. LuidPrivilege = RtlConvertUlongToLuid(m_Privilege);
  120. pNewPrivileges->PrivilegeCount = 1;
  121. pNewPrivileges->Privileges[0].Luid = LuidPrivilege;
  122. pNewPrivileges->Privileges[0].Attributes = m_bEnable ? SE_PRIVILEGE_ENABLED : 0;
  123. Status DBGCHK = NtAdjustPrivilegesToken(
  124. hToken, // TokenHandle
  125. FALSE, // DisableAllPrivileges
  126. pNewPrivileges, // NewPrivileges
  127. sizeof(Buffer1), // BufferLength
  128. pOldPrivileges, // PreviousState (OPTIONAL)
  129. &cbReturnLength // ReturnLength
  130. );
  131. }
  132. if (NT_SUCCESS(Status))
  133. {
  134. if (pOldPrivileges->PrivilegeCount == 0)
  135. {
  136. bWasEnabled = m_bEnable;
  137. }
  138. else
  139. {
  140. bWasEnabled = (pOldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? TRUE : FALSE;
  141. }
  142. if ((!bWasEnabled && m_bEnable) || (bWasEnabled && !m_bEnable))
  143. {
  144. m_hToken = hToken;
  145. hToken = NULL;
  146. SspiPrint(SSPI_LOG, TEXT("TPrivilege::Initialize %s privilege %#x for %s token %p\n"),
  147. m_bEnable ? TEXT("enables") : TEXT("disables"),
  148. m_Privilege,
  149. bIsImpersonation ? TEXT("thread") : TEXT("process"),
  150. m_hToken);
  151. }
  152. }
  153. //
  154. // Map the success code NOT_ALL_ASSIGNED to an appropriate error
  155. // since we're only trying to adjust the one privilege.
  156. //
  157. if (STATUS_NOT_ALL_ASSIGNED == (NTSTATUS) Status )
  158. {
  159. Status DBGCHK = STATUS_PRIVILEGE_NOT_HELD;
  160. }
  161. if (hToken)
  162. {
  163. NtClose(hToken);
  164. }
  165. return Status;
  166. }