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.

153 lines
5.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: priv.cpp
  8. //
  9. // Provides support for enabling/disabling privileges
  10. //
  11. //--------------------------------------------------------------------------
  12. #include "pch.h"
  13. /*******************************************************************
  14. NAME: EnablePrivileges
  15. SYNOPSIS: Enables the given privileges in the current token
  16. ENTRY: pdwPrivileges - list of privileges to enable
  17. RETURNS: On success, the previous thread handle (if present) or NULL
  18. On failure, INVALID_HANDLE_VALUE
  19. NOTES: The returned handle should be passed to ReleasePrivileges
  20. to ensure proper cleanup. Otherwise, if not NULL or
  21. INVALID_HANDLE_VALUE it should be closed with CloseHandle.
  22. HISTORY:
  23. JeffreyS 08-Oct-1996 Created
  24. ********************************************************************/
  25. HANDLE EnablePrivileges(PDWORD pdwPrivileges, ULONG cPrivileges)
  26. {
  27. BOOL fResult;
  28. HANDLE hToken;
  29. HANDLE hOriginalThreadToken;
  30. PTOKEN_PRIVILEGES ptp;
  31. ULONG nBufferSize;
  32. if (!pdwPrivileges || !cPrivileges)
  33. return INVALID_HANDLE_VALUE;
  34. // Note that TOKEN_PRIVILEGES includes a single LUID_AND_ATTRIBUTES
  35. nBufferSize = sizeof(TOKEN_PRIVILEGES) + (cPrivileges - 1)*sizeof(LUID_AND_ATTRIBUTES);
  36. ptp = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, nBufferSize);
  37. if (!ptp)
  38. return INVALID_HANDLE_VALUE;
  39. //
  40. // Initialize the Privileges Structure
  41. //
  42. ptp->PrivilegeCount = cPrivileges;
  43. for (ULONG i = 0; i < cPrivileges; i++)
  44. {
  45. //ptp->Privileges[i].Luid = RtlConvertUlongToLuid(*pdwPrivileges++);
  46. ptp->Privileges[i].Luid.LowPart = *pdwPrivileges++;
  47. ptp->Privileges[i].Luid.HighPart = 0;
  48. ptp->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
  49. }
  50. //
  51. // Open the Token
  52. //
  53. hToken = hOriginalThreadToken = INVALID_HANDLE_VALUE;
  54. fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken);
  55. if (fResult)
  56. hOriginalThreadToken = hToken; // Remember the thread token
  57. else
  58. fResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken);
  59. if (fResult)
  60. {
  61. HANDLE hNewToken;
  62. //
  63. // Duplicate that Token
  64. //
  65. fResult = DuplicateTokenEx(hToken,
  66. TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  67. NULL, // PSECURITY_ATTRIBUTES
  68. SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
  69. TokenImpersonation, // TokenType
  70. &hNewToken); // Duplicate token
  71. if (fResult)
  72. {
  73. //
  74. // Add new privileges
  75. //
  76. fResult = AdjustTokenPrivileges(hNewToken, // TokenHandle
  77. FALSE, // DisableAllPrivileges
  78. ptp, // NewState
  79. 0, // BufferLength
  80. NULL, // PreviousState
  81. NULL); // ReturnLength
  82. if (fResult)
  83. {
  84. //
  85. // Begin impersonating with the new token
  86. //
  87. fResult = SetThreadToken(NULL, hNewToken);
  88. }
  89. CloseHandle(hNewToken);
  90. }
  91. }
  92. // If something failed, don't return a token
  93. if (!fResult)
  94. hOriginalThreadToken = INVALID_HANDLE_VALUE;
  95. // Close the original token if we aren't returning it
  96. if (hOriginalThreadToken == INVALID_HANDLE_VALUE && hToken != INVALID_HANDLE_VALUE)
  97. CloseHandle(hToken);
  98. // If we succeeded, but there was no original thread token,
  99. // return NULL to indicate we need to do SetThreadToken(NULL, NULL)
  100. // to release privs.
  101. if (fResult && hOriginalThreadToken == INVALID_HANDLE_VALUE)
  102. hOriginalThreadToken = NULL;
  103. LocalFree(ptp);
  104. return hOriginalThreadToken;
  105. }
  106. /*******************************************************************
  107. NAME: ReleasePrivileges
  108. SYNOPSIS: Resets privileges to the state prior to the corresponding
  109. EnablePrivileges call.
  110. ENTRY: hToken - result of call to EnablePrivileges
  111. RETURNS: nothing
  112. HISTORY:
  113. JeffreyS 08-Oct-1996 Created
  114. ********************************************************************/
  115. void ReleasePrivileges(HANDLE hToken)
  116. {
  117. if (INVALID_HANDLE_VALUE != hToken)
  118. {
  119. SetThreadToken(NULL, hToken);
  120. if (hToken)
  121. CloseHandle(hToken);
  122. }
  123. }