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.

336 lines
8.1 KiB

  1. /*===================================================================
  2. Microsoft Internet Information Server
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. File: TokenAcl.cxx
  6. Owner: AndrewS
  7. This file contains code related to NT security on impersonation tokens
  8. ===================================================================*/
  9. #include "tcpdllp.hxx"
  10. #pragma hdrstop
  11. // Local Defines
  12. // Local functions
  13. HRESULT ExpandAcl(PACL paclOld, ULONG cbAclOld, PACL *ppAclNew, PSID psid);
  14. HRESULT AddSidToTokenAcl(HANDLE hToken, PSID pSid, ACCESS_MASK amDesiredAccess);
  15. HRESULT GetEveryoneSid(PSID *ppSidEveryone);
  16. /*===================================================================
  17. GrantAllAccessToToken
  18. Given an impersonation token, grant "Everyone" permissions to that
  19. token so that Out Of Proc ISAPIs will be able to do a GetThreadToken call.
  20. Parameters:
  21. HANDLE hToken - handle to impersonation token for a user
  22. Returns:
  23. HRESULT NOERROR on success
  24. ===================================================================*/
  25. HRESULT GrantAllAccessToToken
  26. (
  27. HANDLE hToken
  28. )
  29. {
  30. HRESULT hr = NOERROR;
  31. DWORD err;
  32. PSID pSidEveryone;
  33. hr = GetEveryoneSid(&pSidEveryone);
  34. if (FAILED(hr))
  35. goto LExit;
  36. hr = AddSidToTokenAcl(hToken, pSidEveryone, TOKEN_ALL_ACCESS);
  37. FreeSid( pSidEveryone );
  38. LExit:
  39. DBG_ASSERT(SUCCEEDED(hr));
  40. return(hr);
  41. }
  42. /*===================================================================
  43. AddSidToTokenAcl
  44. When creating Local server objects (e.g. EXE's) we have some problems because of DCOM security.
  45. The user creating the object must have appropriate permissions on the IIS process WindowStation (bug 549)
  46. and the Desktop.
  47. Add ACE's on the ACL for our WindowStation & Desktop for the current user.
  48. Parameters:
  49. HANDLE hImpersonate - handle to impersonation token for the current user
  50. Returns:
  51. HRESULT NOERROR on success
  52. ===================================================================*/
  53. HRESULT AddSidToTokenAcl
  54. (
  55. HANDLE hToken,
  56. PSID pSid,
  57. ACCESS_MASK amDesiredAccess
  58. )
  59. {
  60. HRESULT hr;
  61. DWORD err;
  62. PSECURITY_DESCRIPTOR psdRelative = NULL;
  63. SECURITY_DESCRIPTOR sdAbsolute;
  64. ULONG cbSdPost;
  65. PACL pDacl = NULL;
  66. PACL pDaclNew = NULL;
  67. ULONG cbSD;
  68. ULONG cbDacl;
  69. ULONG cbSacl;
  70. ULONG cbOwner;
  71. ULONG cbGroup;
  72. ACL_SIZE_INFORMATION AclSize;
  73. //
  74. // Get the SD of the token.
  75. // Call this twice; once to get the size, then again to get the info
  76. //
  77. GetKernelObjectSecurity(hToken,
  78. DACL_SECURITY_INFORMATION,
  79. NULL,
  80. 0,
  81. &cbSD);
  82. psdRelative = (PSECURITY_DESCRIPTOR) new BYTE[cbSD];
  83. if (psdRelative == NULL)
  84. {
  85. hr = E_OUTOFMEMORY;
  86. goto LExit;
  87. }
  88. if (!GetKernelObjectSecurity(hToken,
  89. DACL_SECURITY_INFORMATION,
  90. psdRelative,
  91. cbSD,
  92. &cbSD))
  93. {
  94. DBG_ASSERT(FALSE);
  95. err = GetLastError();
  96. hr = HRESULT_FROM_WIN32(err);
  97. goto LExit;
  98. }
  99. //
  100. // Allocate a new Dacl
  101. //
  102. pDacl = (PACL) new BYTE[cbSD];
  103. if (pDacl == NULL)
  104. {
  105. hr = E_OUTOFMEMORY;
  106. goto LExit;
  107. }
  108. //
  109. // Make an absolute SD from the relative SD we have, and get the Dacl at the same time
  110. //
  111. cbSdPost = sizeof(sdAbsolute);
  112. cbDacl = cbSD;
  113. cbSacl = 0;
  114. cbOwner = 0;
  115. cbGroup = 0;
  116. if (!MakeAbsoluteSD(psdRelative,
  117. &sdAbsolute,
  118. &cbSdPost,
  119. pDacl,
  120. &cbDacl,
  121. NULL,
  122. &cbSacl,
  123. NULL,
  124. &cbOwner,
  125. NULL,
  126. &cbGroup))
  127. {
  128. DBG_ASSERT(FALSE);
  129. err = GetLastError();
  130. hr = HRESULT_FROM_WIN32(err);
  131. goto LExit;
  132. }
  133. //
  134. // Copy ACEs over
  135. //
  136. hr = ExpandAcl(pDacl, cbSD, &pDaclNew, pSid);
  137. if (FAILED(hr))
  138. goto LExit;
  139. //
  140. // Add ACE to allow access
  141. //
  142. if (!AddAccessAllowedAce(pDaclNew, ACL_REVISION, amDesiredAccess, pSid))
  143. {
  144. DBG_ASSERT(FALSE);
  145. err = GetLastError();
  146. hr = HRESULT_FROM_WIN32(err);
  147. goto LExit;
  148. }
  149. //
  150. // Set the new DACL in the SD
  151. //
  152. if (!SetSecurityDescriptorDacl(&sdAbsolute, TRUE, pDaclNew, FALSE))
  153. {
  154. DBG_ASSERT(FALSE);
  155. err = GetLastError();
  156. hr = HRESULT_FROM_WIN32(err);
  157. goto LExit;
  158. }
  159. //
  160. // Set the new SD on the token object
  161. //
  162. if (!SetKernelObjectSecurity(hToken, DACL_SECURITY_INFORMATION, &sdAbsolute))
  163. {
  164. DBG_ASSERT(FALSE);
  165. err = GetLastError();
  166. hr = HRESULT_FROM_WIN32(err);
  167. goto LExit;
  168. }
  169. LExit:
  170. delete pDacl;
  171. delete pDaclNew;
  172. delete psdRelative;
  173. return hr;
  174. }
  175. /*===================================================================
  176. GetEveryoneSid
  177. Get a sid for "Everyone"
  178. Parameters:
  179. PSID pSidEveryone
  180. Returns:
  181. HRESULT NOERROR on success
  182. ===================================================================*/
  183. HRESULT GetEveryoneSid
  184. (
  185. PSID *ppSidEveryone
  186. )
  187. {
  188. BOOL fT;
  189. SID_IDENTIFIER_AUTHORITY sidWorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
  190. fT = AllocateAndInitializeSid(
  191. &sidWorldAuthority, // pIdentifierAuthority
  192. 1, // nSubAuthorityCount
  193. SECURITY_WORLD_RID, // nSubAuthority0
  194. 0, // nSubAuthority1
  195. 0, // nSubAuthority2
  196. 0, // nSubAuthority3
  197. 0, // nSubAuthority4
  198. 0, // nSubAuthority5
  199. 0, // nSubAuthority6
  200. 0, // nSubAuthority7
  201. ppSidEveryone // pSid
  202. );
  203. if( !fT )
  204. return HRESULT_FROM_WIN32(GetLastError());
  205. else
  206. return NOERROR;
  207. }
  208. /*===================================================================
  209. ExpandAcl
  210. Support routine for AddWindowStationSecurity.
  211. Expands the given ACL so that there is room for an additional ACE
  212. Parameters:
  213. paclOld - the old ACL to expand
  214. ppAclNew - the newly allocated expanded acl
  215. psid - the sid to use
  216. Returns:
  217. HRESULT NOERROR on success
  218. ===================================================================*/
  219. HRESULT ExpandAcl
  220. (
  221. PACL paclOld,
  222. ULONG cbAclOld,
  223. PACL *ppAclNew,
  224. PSID psid
  225. )
  226. {
  227. HRESULT hr;
  228. DWORD err;
  229. PACL pAclNew = NULL;
  230. ACL_SIZE_INFORMATION asi;
  231. int dwAclSize;
  232. DWORD iAce;
  233. LPVOID pAce;
  234. DBG_ASSERT(paclOld != NULL);
  235. DBG_ASSERT(ppAclNew != NULL);
  236. //
  237. // Create a new ACL to play with
  238. //
  239. if (!GetAclInformation (paclOld, (LPVOID) &asi, (DWORD) sizeof (asi), AclSizeInformation))
  240. goto LExit;
  241. dwAclSize = cbAclOld + GetLengthSid(psid) + (8 * sizeof(DWORD));
  242. pAclNew = (PACL) new BYTE[dwAclSize];
  243. if (pAclNew == NULL)
  244. {
  245. return(E_OUTOFMEMORY);
  246. }
  247. if (!InitializeAcl(pAclNew, dwAclSize, ACL_REVISION))
  248. goto LExit;
  249. //
  250. // Copy all of the ACEs to the new ACL
  251. //
  252. for (iAce = 0; iAce < asi.AceCount; iAce++)
  253. {
  254. //
  255. // Get the ACE and header info
  256. //
  257. if (!GetAce(paclOld, iAce, &pAce))
  258. goto LExit;
  259. //
  260. // Add the ACE to the new list
  261. //
  262. if (!AddAce(pAclNew, ACL_REVISION, iAce, pAce, ((ACE_HEADER *)pAce)->AceSize))
  263. goto LExit;
  264. }
  265. *ppAclNew = pAclNew;
  266. return(NOERROR);
  267. LExit:
  268. if (pAclNew != NULL)
  269. delete pAclNew;
  270. DBG_ASSERT(FALSE);
  271. err = GetLastError();
  272. hr = HRESULT_FROM_WIN32(err);
  273. return hr;
  274. }