Source code of Windows XP (NT5)
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.2 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: security.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #pragma hdrstop
  12. #include "security.h"
  13. DWORD
  14. Security_SetPrivilegeAttrib(
  15. LPCTSTR PrivilegeName,
  16. DWORD NewPrivilegeAttribute,
  17. DWORD *OldPrivilegeAttribute
  18. )
  19. {
  20. LUID PrivilegeValue;
  21. TOKEN_PRIVILEGES TokenPrivileges, OldTokenPrivileges;
  22. DWORD ReturnLength;
  23. HANDLE TokenHandle;
  24. //
  25. // First, find out the LUID Value of the privilege
  26. //
  27. if(!LookupPrivilegeValue(NULL, PrivilegeName, &PrivilegeValue))
  28. {
  29. return GetLastError();
  30. }
  31. //
  32. // Get the token handle
  33. //
  34. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
  35. {
  36. return GetLastError();
  37. }
  38. //
  39. // Set up the privilege set we will need
  40. //
  41. TokenPrivileges.PrivilegeCount = 1;
  42. TokenPrivileges.Privileges[0].Luid = PrivilegeValue;
  43. TokenPrivileges.Privileges[0].Attributes = NewPrivilegeAttribute;
  44. ReturnLength = sizeof(TOKEN_PRIVILEGES);
  45. if (!AdjustTokenPrivileges(
  46. TokenHandle,
  47. FALSE,
  48. &TokenPrivileges,
  49. sizeof(TOKEN_PRIVILEGES),
  50. &OldTokenPrivileges,
  51. &ReturnLength
  52. ))
  53. {
  54. CloseHandle(TokenHandle);
  55. return GetLastError();
  56. }
  57. else
  58. {
  59. if (NULL != OldPrivilegeAttribute)
  60. {
  61. *OldPrivilegeAttribute = OldTokenPrivileges.Privileges[0].Attributes;
  62. }
  63. CloseHandle(TokenHandle);
  64. return ERROR_SUCCESS;
  65. }
  66. }
  67. //
  68. // Returns the SID of the currently logged on user.
  69. // If the function succeeds, use the LocalFree API to
  70. // free the returned SID structure.
  71. //
  72. HRESULT
  73. GetCurrentUserSid(
  74. PSID *ppsid
  75. )
  76. {
  77. HRESULT hr = E_FAIL;
  78. DWORD dwErr = 0;
  79. //
  80. // Get the token handle. First try the thread token then the process
  81. // token. If these fail we return early. No sense in continuing
  82. // on if we can't get a user token.
  83. //
  84. *ppsid = NULL;
  85. CWin32Handle hToken;
  86. if (!OpenThreadToken(GetCurrentThread(),
  87. TOKEN_READ,
  88. TRUE,
  89. hToken.HandlePtr()))
  90. {
  91. if (ERROR_NO_TOKEN == GetLastError())
  92. {
  93. if (!OpenProcessToken(GetCurrentProcess(),
  94. TOKEN_READ,
  95. hToken.HandlePtr()))
  96. {
  97. dwErr = GetLastError();
  98. return HRESULT_FROM_WIN32(dwErr);
  99. }
  100. }
  101. else
  102. {
  103. dwErr = GetLastError();
  104. return HRESULT_FROM_WIN32(dwErr);
  105. }
  106. }
  107. //
  108. // Find operator's SID.
  109. //
  110. LPBYTE pbTokenInfo = NULL;
  111. DWORD cbTokenInfo = 0;
  112. cbTokenInfo = 0;
  113. if (!GetTokenInformation(hToken,
  114. TokenUser,
  115. NULL,
  116. cbTokenInfo,
  117. &cbTokenInfo))
  118. {
  119. dwErr = GetLastError();
  120. if (ERROR_INSUFFICIENT_BUFFER == dwErr)
  121. {
  122. pbTokenInfo = new BYTE[cbTokenInfo];
  123. if (NULL == pbTokenInfo)
  124. hr = E_OUTOFMEMORY;
  125. }
  126. else
  127. {
  128. dwErr = GetLastError();
  129. hr = HRESULT_FROM_WIN32(dwErr);
  130. }
  131. }
  132. if (NULL != pbTokenInfo)
  133. {
  134. //
  135. // Get the user token information.
  136. //
  137. if (!GetTokenInformation(hToken,
  138. TokenUser,
  139. pbTokenInfo,
  140. cbTokenInfo,
  141. &cbTokenInfo))
  142. {
  143. dwErr = GetLastError();
  144. hr = HRESULT_FROM_WIN32(dwErr);
  145. }
  146. else
  147. {
  148. SID_AND_ATTRIBUTES *psa = (SID_AND_ATTRIBUTES *)pbTokenInfo;
  149. int cbSid = GetLengthSid(psa->Sid);
  150. PSID psid = (PSID)LocalAlloc(LPTR, cbSid);
  151. if (NULL != psid)
  152. {
  153. CopySid(cbSid, psid, psa->Sid);
  154. if (IsValidSid(psid))
  155. {
  156. //
  157. // SID is valid. Transfer buffer to caller.
  158. //
  159. *ppsid = psid;
  160. hr = NOERROR;
  161. }
  162. else
  163. {
  164. //
  165. // SID is invalid.
  166. //
  167. LocalFree(psid);
  168. hr = HRESULT_FROM_WIN32(ERROR_INVALID_SID);
  169. }
  170. }
  171. else
  172. {
  173. hr = E_OUTOFMEMORY;
  174. }
  175. }
  176. delete[] pbTokenInfo;
  177. }
  178. return hr;
  179. }
  180. //
  181. // Determines if a given SID is that of the current user.
  182. //
  183. BOOL IsSidCurrentUser(PSID psid)
  184. {
  185. BOOL bIsCurrent = FALSE;
  186. PSID psidUser;
  187. if (SUCCEEDED(GetCurrentUserSid(&psidUser)))
  188. {
  189. bIsCurrent = EqualSid(psid, psidUser);
  190. LocalFree(psidUser);
  191. }
  192. return bIsCurrent;
  193. }