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.

436 lines
10 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. ooptoken.cpp
  5. Abstract:
  6. Implementation of the CWamOopTokenInfo object
  7. Author:
  8. Taylor Weiss ( TaylorW ) 15-Feb-1999
  9. Environment:
  10. User Mode - Win32
  11. Project:
  12. iis\svcs\wam\object
  13. --*/
  14. #include <isapip.hxx>
  15. #include "ooptoken.h"
  16. /************************ CWamOopTokenInfo ****************************/
  17. CWamOopTokenInfo * CWamOopTokenInfo::ms_pInstance = NULL;
  18. HRESULT
  19. CWamOopTokenInfo::Create( VOID )
  20. /*++
  21. Routine Description:
  22. Create and initialize ms_pInstance. Get the wam and system SIDs.
  23. The IWAM_* user sid is obtained from the process token. This
  24. only works if we are running OOP. The alternative is to put this
  25. in w3svc or infocomm and get the SID from the metabase. The downside
  26. to that is the account for the application package is exposed
  27. through the com+ UI, so it can be changed without a metabase update.
  28. Parameters
  29. Return Value
  30. HRESULT
  31. --*/
  32. {
  33. DBG_ASSERT( CWamOopTokenInfo::ms_pInstance == NULL );
  34. HRESULT hr = NOERROR;
  35. HANDLE hProcessToken = NULL;
  36. LPVOID pvUserBuffer = NULL;
  37. PSID pSidSys = NULL;
  38. CWamOopTokenInfo * pInstance = NULL;
  39. do
  40. {
  41. BOOL fNoError = FALSE;
  42. DWORD cbUserBuffer = 0;
  43. // Allocate instance
  44. pInstance = new CWamOopTokenInfo();
  45. DBG_ASSERT( pInstance != NULL );
  46. if( !pInstance )
  47. {
  48. DBG_ASSERT( pInstance );
  49. hr = E_OUTOFMEMORY;
  50. break;
  51. }
  52. //
  53. // Get a SID for the IWAM_* user.
  54. //
  55. fNoError = OpenProcessToken( GetCurrentProcess(),
  56. TOKEN_QUERY,
  57. &hProcessToken
  58. );
  59. if( !fNoError )
  60. {
  61. DBG_ASSERT( fNoError );
  62. hr = HRESULT_FROM_WIN32( GetLastError() );
  63. break;
  64. }
  65. // Get buffer size
  66. fNoError = GetTokenInformation( hProcessToken,
  67. TokenUser,
  68. NULL,
  69. 0,
  70. &cbUserBuffer
  71. );
  72. DBG_ASSERT( fNoError == FALSE );
  73. pvUserBuffer = LocalAlloc( LPTR, cbUserBuffer );
  74. DBG_ASSERT( pvUserBuffer != NULL );
  75. if( !pvUserBuffer )
  76. {
  77. DBG_ASSERT( pvUserBuffer );
  78. hr = E_OUTOFMEMORY;
  79. break;
  80. }
  81. // Get user info
  82. fNoError = GetTokenInformation( hProcessToken,
  83. TokenUser,
  84. pvUserBuffer,
  85. cbUserBuffer,
  86. &cbUserBuffer
  87. );
  88. if( !fNoError )
  89. {
  90. DBG_ASSERT( fNoError );
  91. hr = HRESULT_FROM_WIN32( GetLastError() );
  92. break;
  93. }
  94. hr = pInstance->SetIWAMUserSid( ((TOKEN_USER *)pvUserBuffer)->User.Sid );
  95. if( FAILED(hr) ) break;
  96. //
  97. // Create a SID for the local system
  98. //
  99. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  100. fNoError = AllocateAndInitializeSid( &siaNtAuthority,
  101. 1,
  102. SECURITY_LOCAL_SYSTEM_RID,
  103. 0, 0, 0, 0, 0, 0, 0,
  104. &pSidSys
  105. );
  106. if( !fNoError )
  107. {
  108. DBG_ASSERT( fNoError );
  109. hr = HRESULT_FROM_WIN32( GetLastError() );
  110. break;
  111. }
  112. hr = pInstance->SetSystemSid( pSidSys );
  113. if( FAILED(hr) ) break;
  114. CWamOopTokenInfo::ms_pInstance = pInstance;
  115. } while( FALSE );
  116. if( hProcessToken )
  117. {
  118. CloseHandle( hProcessToken );
  119. }
  120. if( pvUserBuffer )
  121. {
  122. LocalFree( pvUserBuffer );
  123. }
  124. if( pSidSys )
  125. {
  126. FreeSid( pSidSys );
  127. }
  128. if( CWamOopTokenInfo::ms_pInstance == NULL )
  129. {
  130. // We hit some break, need to dealloc local pointer
  131. delete pInstance;
  132. }
  133. DBG_ASSERT( CWamOopTokenInfo::ms_pInstance != NULL );
  134. DBG_ASSERT( SUCCEEDED(hr) );
  135. return hr;
  136. }
  137. HRESULT
  138. CWamOopTokenInfo::SetIWAMUserSid( PSID pSid )
  139. /*++
  140. Routine Description:
  141. Make a local copy of the SID. Called during instance create.
  142. Probably should avoid the extra duplication.
  143. Parameters
  144. pSid - The IWAM_* user sid.
  145. Return Value
  146. HRESULT
  147. --*/
  148. {
  149. DBG_ASSERT( pSid );
  150. DBG_ASSERT( m_pIWAMUserSid == NULL );
  151. DBG_ASSERT( m_cbIWAMUserSid == 0 );
  152. HRESULT hr = NOERROR;
  153. m_cbIWAMUserSid = GetLengthSid( pSid );
  154. m_pIWAMUserSid = LocalAlloc( LPTR, m_cbIWAMUserSid );
  155. if( m_pIWAMUserSid )
  156. {
  157. if( !CopySid( m_cbIWAMUserSid, m_pIWAMUserSid, pSid ) )
  158. {
  159. hr = HRESULT_FROM_WIN32( GetLastError() );
  160. }
  161. }
  162. else
  163. {
  164. hr = E_OUTOFMEMORY;
  165. m_cbIWAMUserSid = 0;
  166. }
  167. DBG_ASSERT( m_pIWAMUserSid );
  168. DBG_ASSERT( m_cbIWAMUserSid > 0 );
  169. DBG_ASSERT( SUCCEEDED(hr) );
  170. return hr;
  171. }
  172. HRESULT
  173. CWamOopTokenInfo::SetSystemSid( PSID pSid )
  174. /*++
  175. Routine Description:
  176. Make a local copy of the SID. Called during instance create.
  177. Probably should avoid the extra duplication.
  178. Parameters
  179. pSid - The system sid.
  180. Return Value
  181. HRESULT
  182. --*/
  183. {
  184. DBG_ASSERT( pSid );
  185. DBG_ASSERT( m_pSystemSid == NULL );
  186. DBG_ASSERT( m_cbSystemSid == 0 );
  187. HRESULT hr = NOERROR;
  188. m_cbSystemSid = GetLengthSid( pSid );
  189. m_pSystemSid = LocalAlloc( LPTR, m_cbSystemSid );
  190. if( m_pSystemSid )
  191. {
  192. if( !CopySid( m_cbSystemSid, m_pSystemSid, pSid ) )
  193. {
  194. hr = HRESULT_FROM_WIN32( GetLastError() );
  195. }
  196. }
  197. else
  198. {
  199. hr = E_OUTOFMEMORY;
  200. m_cbSystemSid = 0;
  201. }
  202. DBG_ASSERT( m_pSystemSid );
  203. DBG_ASSERT( m_cbSystemSid > 0 );
  204. DBG_ASSERT( SUCCEEDED(hr) );
  205. return hr;
  206. }
  207. HRESULT
  208. CWamOopTokenInfo::ModifyTokenForOop
  209. (
  210. HANDLE hThreadToken
  211. )
  212. /*++
  213. Routine Description
  214. Add the IWAM_* ace to the token.
  215. Prameters
  216. HANDLE hThreadToken - The token to modify.
  217. Return Value
  218. HRESULT
  219. --*/
  220. {
  221. DBG_ASSERT( m_pIWAMUserSid );
  222. DBG_ASSERT( m_pSystemSid );
  223. HRESULT hr = NOERROR;
  224. DWORD cbTokenUserBuffer = 0;
  225. LPVOID pvTokenUserBuffer = NULL;
  226. DWORD cbNewAcl = 0;
  227. PACL pNewAcl = NULL;
  228. do
  229. {
  230. BOOL bRet;
  231. //
  232. // Get the User SID from the token
  233. //
  234. // Get buffer size
  235. bRet = GetTokenInformation( hThreadToken,
  236. TokenUser,
  237. NULL,
  238. 0,
  239. &cbTokenUserBuffer
  240. );
  241. DBG_ASSERT( bRet == FALSE );
  242. pvTokenUserBuffer = LocalAlloc( LPTR, cbTokenUserBuffer );
  243. if( !pvTokenUserBuffer )
  244. {
  245. DBG_ASSERT( pvTokenUserBuffer );
  246. hr = E_OUTOFMEMORY;
  247. break;
  248. }
  249. // Get TokenUser
  250. bRet = GetTokenInformation( hThreadToken,
  251. TokenUser,
  252. pvTokenUserBuffer,
  253. cbTokenUserBuffer,
  254. &cbTokenUserBuffer
  255. );
  256. if( !bRet )
  257. {
  258. DBG_ASSERT( bRet );
  259. hr = HRESULT_FROM_WIN32( GetLastError() );
  260. break;
  261. }
  262. PSID pSidUser = ((TOKEN_USER *)pvTokenUserBuffer)->User.Sid;
  263. DBG_ASSERT( pSidUser );
  264. //
  265. // Allocate and init our new ACL
  266. //
  267. cbNewAcl = sizeof(ACL) +
  268. sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pSidUser) - sizeof(DWORD) +
  269. sizeof(ACCESS_ALLOWED_ACE) + m_cbSystemSid - sizeof(DWORD) +
  270. sizeof(ACCESS_ALLOWED_ACE) + m_cbIWAMUserSid - sizeof(DWORD);
  271. pNewAcl = (PACL)LocalAlloc( LPTR, cbNewAcl );
  272. if( !pNewAcl )
  273. {
  274. DBG_ASSERT( pNewAcl );
  275. hr = E_OUTOFMEMORY;
  276. break;
  277. }
  278. bRet = InitializeAcl( pNewAcl, cbNewAcl, ACL_REVISION );
  279. if( !bRet )
  280. {
  281. DBG_ASSERT( bRet );
  282. hr = HRESULT_FROM_WIN32( GetLastError() );
  283. break;
  284. }
  285. //
  286. // Add the aces
  287. //
  288. bRet = AddAccessAllowedAce( pNewAcl,
  289. ACL_REVISION,
  290. GENERIC_ALL | STANDARD_RIGHTS_ALL,
  291. pSidUser
  292. );
  293. if( !bRet )
  294. {
  295. DBG_ASSERT( bRet );
  296. hr = HRESULT_FROM_WIN32( GetLastError() );
  297. break;
  298. }
  299. bRet = AddAccessAllowedAce( pNewAcl,
  300. ACL_REVISION,
  301. GENERIC_ALL | STANDARD_RIGHTS_ALL,
  302. m_pSystemSid
  303. );
  304. if( !bRet )
  305. {
  306. DBG_ASSERT( bRet );
  307. hr = HRESULT_FROM_WIN32( GetLastError() );
  308. break;
  309. }
  310. bRet = AddAccessAllowedAce( pNewAcl,
  311. ACL_REVISION,
  312. GENERIC_ALL | STANDARD_RIGHTS_ALL,
  313. m_pIWAMUserSid
  314. );
  315. if( !bRet )
  316. {
  317. DBG_ASSERT( bRet );
  318. hr = HRESULT_FROM_WIN32( GetLastError() );
  319. break;
  320. }
  321. // Blast the new DACL into our token
  322. TOKEN_DEFAULT_DACL tddNew;
  323. tddNew.DefaultDacl = pNewAcl;
  324. bRet = SetTokenInformation( hThreadToken,
  325. TokenDefaultDacl,
  326. &tddNew,
  327. cbNewAcl
  328. );
  329. if( !bRet )
  330. {
  331. DBG_ASSERT( bRet );
  332. hr = HRESULT_FROM_WIN32( GetLastError() );
  333. break;
  334. }
  335. }while(FALSE);
  336. if( pvTokenUserBuffer )
  337. {
  338. LocalFree( pvTokenUserBuffer );
  339. }
  340. if( pNewAcl )
  341. {
  342. LocalFree( pNewAcl );
  343. }
  344. DBG_ASSERT( SUCCEEDED(hr) );
  345. return hr;
  346. }