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.

1113 lines
31 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. NTacls
  5. Abstract:
  6. This module implements the CSecurityAttribute class. It's job is to
  7. encapsulate the NT security descriptors as needed by Calais.
  8. Author:
  9. Doug Barlow (dbarlow) 1/24/1997
  10. Environment:
  11. Windows NT, Win32, C++ w/ Exceptions
  12. Notes:
  13. ?Notes?
  14. --*/
  15. #ifndef WIN32_LEAN_AND_MEAN
  16. #define WIN32_LEAN_AND_MEAN
  17. #endif
  18. #include <windows.h>
  19. #include "cspUtils.h"
  20. const CSecurityDescriptor::SecurityId
  21. CSecurityDescriptor::SID_Null = { SECURITY_NULL_SID_AUTHORITY, 1, SECURITY_NULL_RID, 0 },
  22. CSecurityDescriptor::SID_World = { SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0 },
  23. CSecurityDescriptor::SID_Local = { SECURITY_LOCAL_SID_AUTHORITY, 1, SECURITY_LOCAL_RID, 0 },
  24. CSecurityDescriptor::SID_Owner = { SECURITY_CREATOR_SID_AUTHORITY, 1, SECURITY_CREATOR_OWNER_RID, 0 },
  25. CSecurityDescriptor::SID_Group = { SECURITY_CREATOR_SID_AUTHORITY, 1, SECURITY_CREATOR_GROUP_RID, 0 },
  26. CSecurityDescriptor::SID_Admins = { SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS },
  27. CSecurityDescriptor::SID_DialUp = { SECURITY_NT_AUTHORITY, 1, SECURITY_DIALUP_RID, 0 },
  28. CSecurityDescriptor::SID_Network = { SECURITY_NT_AUTHORITY, 1, SECURITY_NETWORK_RID, 0 },
  29. CSecurityDescriptor::SID_Batch = { SECURITY_NT_AUTHORITY, 1, SECURITY_BATCH_RID, 0 },
  30. CSecurityDescriptor::SID_Interactive = { SECURITY_NT_AUTHORITY, 1, SECURITY_INTERACTIVE_RID, 0 },
  31. CSecurityDescriptor::SID_Service = { SECURITY_NT_AUTHORITY, 1, SECURITY_SERVICE_RID, 0 },
  32. CSecurityDescriptor::SID_System = { SECURITY_NT_AUTHORITY, 1, SECURITY_LOCAL_SYSTEM_RID, 0 },
  33. CSecurityDescriptor::SID_SysDomain = { SECURITY_NT_AUTHORITY, 1, SECURITY_BUILTIN_DOMAIN_RID, 0 };
  34. CSecurityDescriptor::CSecurityDescriptor()
  35. {
  36. m_pSD = NULL;
  37. m_pOwner = NULL;
  38. m_pGroup = NULL;
  39. m_pDACL = NULL;
  40. m_pSACL= NULL;
  41. m_fInheritance = FALSE;
  42. }
  43. CSecurityDescriptor::~CSecurityDescriptor()
  44. {
  45. if (m_pSD)
  46. delete m_pSD;
  47. if (m_pOwner)
  48. delete[] (LPBYTE)m_pOwner;
  49. if (m_pGroup)
  50. delete[] (LPBYTE)m_pGroup;
  51. if (m_pDACL)
  52. delete[] (LPBYTE)m_pDACL;
  53. if (m_pSACL)
  54. delete[] (LPBYTE)m_pSACL;
  55. }
  56. HRESULT CSecurityDescriptor::Initialize()
  57. {
  58. if (m_pSD)
  59. {
  60. delete m_pSD;
  61. m_pSD = NULL;
  62. }
  63. if (m_pOwner)
  64. {
  65. delete[] (LPBYTE)(m_pOwner);
  66. m_pOwner = NULL;
  67. }
  68. if (m_pGroup)
  69. {
  70. delete[] (LPBYTE)(m_pGroup);
  71. m_pGroup = NULL;
  72. }
  73. if (m_pDACL)
  74. {
  75. delete[] (LPBYTE)(m_pDACL);
  76. m_pDACL = NULL;
  77. }
  78. if (m_pSACL)
  79. {
  80. delete[] (LPBYTE)(m_pSACL);
  81. m_pSACL = NULL;
  82. }
  83. m_pSD = new SECURITY_DESCRIPTOR;
  84. if (!m_pSD)
  85. return E_OUTOFMEMORY;
  86. if (!InitializeSecurityDescriptor(m_pSD, SECURITY_DESCRIPTOR_REVISION))
  87. {
  88. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  89. delete m_pSD;
  90. m_pSD = NULL;
  91. _ASSERTE(FALSE);
  92. return hr;
  93. }
  94. // Set the DACL to allow EVERYONE
  95. SetSecurityDescriptorDacl(m_pSD, TRUE, NULL, FALSE);
  96. return S_OK;
  97. }
  98. HRESULT CSecurityDescriptor::InitializeFromProcessToken(BOOL bDefaulted)
  99. {
  100. PSID pUserSid;
  101. PSID pGroupSid;
  102. HRESULT hr;
  103. Initialize();
  104. hr = GetProcessSids(&pUserSid, &pGroupSid);
  105. if (FAILED(hr))
  106. return hr;
  107. hr = SetOwner(pUserSid, bDefaulted);
  108. if (FAILED(hr))
  109. return hr;
  110. hr = SetGroup(pGroupSid, bDefaulted);
  111. if (FAILED(hr))
  112. return hr;
  113. return S_OK;
  114. }
  115. HRESULT CSecurityDescriptor::InitializeFromThreadToken(BOOL bDefaulted, BOOL bRevertToProcessToken)
  116. {
  117. PSID pUserSid;
  118. PSID pGroupSid;
  119. HRESULT hr;
  120. Initialize();
  121. hr = GetThreadSids(&pUserSid, &pGroupSid);
  122. if (HRESULT_CODE(hr) == ERROR_NO_TOKEN && bRevertToProcessToken)
  123. hr = GetProcessSids(&pUserSid, &pGroupSid);
  124. if (FAILED(hr))
  125. return hr;
  126. hr = SetOwner(pUserSid, bDefaulted);
  127. if (FAILED(hr))
  128. return hr;
  129. hr = SetGroup(pGroupSid, bDefaulted);
  130. if (FAILED(hr))
  131. return hr;
  132. return S_OK;
  133. }
  134. HRESULT CSecurityDescriptor::SetOwner(PSID pOwnerSid, BOOL bDefaulted)
  135. {
  136. _ASSERTE(m_pSD);
  137. // Mark the SD as having no owner
  138. if (!SetSecurityDescriptorOwner(m_pSD, NULL, bDefaulted))
  139. {
  140. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  141. _ASSERTE(FALSE);
  142. return hr;
  143. }
  144. if (m_pOwner)
  145. {
  146. delete[] (LPBYTE)(m_pOwner);
  147. m_pOwner = NULL;
  148. }
  149. // If they asked for no owner don't do the copy
  150. if (pOwnerSid == NULL)
  151. return S_OK;
  152. // Make a copy of the Sid for the return value
  153. DWORD dwSize = GetLengthSid(pOwnerSid);
  154. m_pOwner = (PSID) new BYTE[dwSize];
  155. if (!m_pOwner)
  156. {
  157. // Insufficient memory to allocate Sid
  158. _ASSERTE(FALSE);
  159. return E_OUTOFMEMORY;
  160. }
  161. if (!CopySid(dwSize, m_pOwner, pOwnerSid))
  162. {
  163. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  164. _ASSERTE(FALSE);
  165. delete[] (LPBYTE)(m_pOwner);
  166. m_pOwner = NULL;
  167. return hr;
  168. }
  169. _ASSERTE(IsValidSid(m_pOwner));
  170. if (!SetSecurityDescriptorOwner(m_pSD, m_pOwner, bDefaulted))
  171. {
  172. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  173. _ASSERTE(FALSE);
  174. delete[] (LPBYTE)(m_pOwner);
  175. m_pOwner = NULL;
  176. return hr;
  177. }
  178. return S_OK;
  179. }
  180. HRESULT CSecurityDescriptor::SetGroup(PSID pGroupSid, BOOL bDefaulted)
  181. {
  182. _ASSERTE(m_pSD);
  183. // Mark the SD as having no Group
  184. if (!SetSecurityDescriptorGroup(m_pSD, NULL, bDefaulted))
  185. {
  186. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  187. _ASSERTE(FALSE);
  188. return hr;
  189. }
  190. if (m_pGroup)
  191. {
  192. delete[] (LPBYTE)(m_pGroup);
  193. m_pGroup = NULL;
  194. }
  195. // If they asked for no Group don't do the copy
  196. if (pGroupSid == NULL)
  197. return S_OK;
  198. // Make a copy of the Sid for the return value
  199. DWORD dwSize = GetLengthSid(pGroupSid);
  200. m_pGroup = (PSID) new BYTE[dwSize];
  201. if (!m_pGroup)
  202. {
  203. // Insufficient memory to allocate Sid
  204. _ASSERTE(FALSE);
  205. return E_OUTOFMEMORY;
  206. }
  207. if (!CopySid(dwSize, m_pGroup, pGroupSid))
  208. {
  209. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  210. _ASSERTE(FALSE);
  211. delete[] (LPBYTE)(m_pGroup);
  212. m_pGroup = NULL;
  213. return hr;
  214. }
  215. _ASSERTE(IsValidSid(m_pGroup));
  216. if (!SetSecurityDescriptorGroup(m_pSD, m_pGroup, bDefaulted))
  217. {
  218. HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
  219. _ASSERTE(FALSE);
  220. delete[] (LPBYTE)(m_pGroup);
  221. m_pGroup = NULL;
  222. return hr;
  223. }
  224. return S_OK;
  225. }
  226. HRESULT CSecurityDescriptor::Allow(const SecurityId *psidPrincipal, DWORD dwAccessMask)
  227. {
  228. HRESULT hr = AddAccessAllowedACEToACL(&m_pDACL, psidPrincipal, dwAccessMask);
  229. if (SUCCEEDED(hr))
  230. {
  231. if (!SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE))
  232. hr = HRESULT_FROM_WIN32(GetLastError());
  233. }
  234. return hr;
  235. }
  236. HRESULT CSecurityDescriptor::Allow(LPCTSTR pszPrincipal, DWORD dwAccessMask)
  237. {
  238. HRESULT hr = AddAccessAllowedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
  239. if (SUCCEEDED(hr))
  240. {
  241. if (!SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE))
  242. hr = HRESULT_FROM_WIN32(GetLastError());
  243. }
  244. return hr;
  245. }
  246. HRESULT CSecurityDescriptor::Deny(const SecurityId *psidPrincipal, DWORD dwAccessMask)
  247. {
  248. HRESULT hr = AddAccessDeniedACEToACL(&m_pDACL, psidPrincipal, dwAccessMask);
  249. if (SUCCEEDED(hr))
  250. {
  251. if (!SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE))
  252. hr = HRESULT_FROM_WIN32(GetLastError());
  253. }
  254. return hr;
  255. }
  256. HRESULT CSecurityDescriptor::Deny(LPCTSTR pszPrincipal, DWORD dwAccessMask)
  257. {
  258. HRESULT hr = AddAccessDeniedACEToACL(&m_pDACL, pszPrincipal, dwAccessMask);
  259. if (SUCCEEDED(hr))
  260. {
  261. if (!SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE))
  262. hr = HRESULT_FROM_WIN32(GetLastError());
  263. }
  264. return hr;
  265. }
  266. HRESULT CSecurityDescriptor::Revoke(LPCTSTR pszPrincipal)
  267. {
  268. HRESULT hr = RemovePrincipalFromACL(m_pDACL, pszPrincipal);
  269. if (SUCCEEDED(hr))
  270. {
  271. if (!SetSecurityDescriptorDacl(m_pSD, TRUE, m_pDACL, FALSE))
  272. hr = HRESULT_FROM_WIN32(GetLastError());
  273. }
  274. return hr;
  275. }
  276. HRESULT CSecurityDescriptor::GetProcessSids(PSID* ppUserSid, PSID* ppGroupSid)
  277. {
  278. BOOL bRes;
  279. HRESULT hr;
  280. HANDLE hToken = NULL;
  281. if (ppUserSid)
  282. *ppUserSid = NULL;
  283. if (ppGroupSid)
  284. *ppGroupSid = NULL;
  285. bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
  286. if (!bRes)
  287. {
  288. // Couldn't open process token
  289. hr = HRESULT_FROM_WIN32(GetLastError());
  290. _ASSERTE(FALSE);
  291. return hr;
  292. }
  293. hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
  294. return hr;
  295. }
  296. HRESULT CSecurityDescriptor::GetThreadSids(PSID* ppUserSid, PSID* ppGroupSid, BOOL bOpenAsSelf)
  297. {
  298. BOOL bRes;
  299. HRESULT hr;
  300. HANDLE hToken = NULL;
  301. if (ppUserSid)
  302. *ppUserSid = NULL;
  303. if (ppGroupSid)
  304. *ppGroupSid = NULL;
  305. bRes = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, bOpenAsSelf, &hToken);
  306. if (!bRes)
  307. {
  308. // Couldn't open thread token
  309. hr = HRESULT_FROM_WIN32(GetLastError());
  310. return hr;
  311. }
  312. hr = GetTokenSids(hToken, ppUserSid, ppGroupSid);
  313. CloseHandle(hToken);
  314. return hr;
  315. }
  316. HRESULT CSecurityDescriptor::GetTokenSids(HANDLE hToken, PSID* ppUserSid, PSID* ppGroupSid)
  317. {
  318. DWORD dwSize;
  319. HRESULT hr;
  320. PTOKEN_USER ptkUser = NULL;
  321. PTOKEN_PRIMARY_GROUP ptkGroup = NULL;
  322. if (ppUserSid)
  323. *ppUserSid = NULL;
  324. if (ppGroupSid)
  325. *ppGroupSid = NULL;
  326. if (ppUserSid)
  327. {
  328. // Get length required for TokenUser by specifying buffer length of 0
  329. GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
  330. hr = GetLastError();
  331. if (hr != ERROR_INSUFFICIENT_BUFFER)
  332. {
  333. // Expected ERROR_INSUFFICIENT_BUFFER
  334. _ASSERTE(FALSE);
  335. hr = HRESULT_FROM_WIN32(hr);
  336. goto failed;
  337. }
  338. ptkUser = (TOKEN_USER*) new BYTE[dwSize];
  339. if (!ptkUser)
  340. {
  341. // Insufficient memory to allocate TOKEN_USER
  342. _ASSERTE(FALSE);
  343. hr = E_OUTOFMEMORY;
  344. goto failed;
  345. }
  346. // Get Sid of process token.
  347. if (!GetTokenInformation(hToken, TokenUser, ptkUser, dwSize, &dwSize))
  348. {
  349. // Couldn't get user info
  350. hr = HRESULT_FROM_WIN32(GetLastError());
  351. _ASSERTE(FALSE);
  352. goto failed;
  353. }
  354. // Make a copy of the Sid for the return value
  355. dwSize = GetLengthSid(ptkUser->User.Sid);
  356. PSID pSid = (PSID) new BYTE[dwSize];
  357. if (!pSid)
  358. {
  359. // Insufficient memory to allocate Sid
  360. _ASSERTE(FALSE);
  361. hr = E_OUTOFMEMORY;
  362. goto failed;
  363. }
  364. if (!CopySid(dwSize, pSid, ptkUser->User.Sid))
  365. {
  366. hr = HRESULT_FROM_WIN32(GetLastError());
  367. _ASSERTE(FALSE);
  368. goto failed;
  369. }
  370. _ASSERTE(IsValidSid(pSid));
  371. *ppUserSid = pSid;
  372. delete[] (LPBYTE)(ptkUser);
  373. ptkUser = NULL;
  374. }
  375. if (ppGroupSid)
  376. {
  377. // Get length required for TokenPrimaryGroup by specifying buffer length of 0
  378. GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwSize);
  379. hr = GetLastError();
  380. if (hr != ERROR_INSUFFICIENT_BUFFER)
  381. {
  382. // Expected ERROR_INSUFFICIENT_BUFFER
  383. _ASSERTE(FALSE);
  384. hr = HRESULT_FROM_WIN32(hr);
  385. goto failed;
  386. }
  387. ptkGroup = (TOKEN_PRIMARY_GROUP*) new BYTE[dwSize];
  388. if (!ptkGroup)
  389. {
  390. // Insufficient memory to allocate TOKEN_USER
  391. _ASSERTE(FALSE);
  392. hr = E_OUTOFMEMORY;
  393. goto failed;
  394. }
  395. // Get Sid of process token.
  396. if (!GetTokenInformation(hToken, TokenPrimaryGroup, ptkGroup, dwSize, &dwSize))
  397. {
  398. // Couldn't get user info
  399. hr = HRESULT_FROM_WIN32(GetLastError());
  400. _ASSERTE(FALSE);
  401. goto failed;
  402. }
  403. // Make a copy of the Sid for the return value
  404. dwSize = GetLengthSid(ptkGroup->PrimaryGroup);
  405. PSID pSid = (PSID) new BYTE[dwSize];
  406. if (!pSid)
  407. {
  408. // Insufficient memory to allocate Sid
  409. _ASSERTE(FALSE);
  410. hr = E_OUTOFMEMORY;
  411. goto failed;
  412. }
  413. if (!CopySid(dwSize, pSid, ptkGroup->PrimaryGroup))
  414. {
  415. hr = HRESULT_FROM_WIN32(GetLastError());
  416. _ASSERTE(FALSE);
  417. goto failed;
  418. }
  419. _ASSERTE(IsValidSid(pSid));
  420. *ppGroupSid = pSid;
  421. delete[] (LPBYTE)(ptkGroup);
  422. ptkGroup = NULL;
  423. }
  424. return S_OK;
  425. failed:
  426. if (ptkUser)
  427. delete[] (LPBYTE)(ptkUser);
  428. if (ptkGroup)
  429. delete[] (LPBYTE)(ptkGroup);
  430. return hr;
  431. }
  432. HRESULT CSecurityDescriptor::GetCurrentUserSID(PSID *ppSid)
  433. {
  434. HANDLE tkHandle;
  435. if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkHandle))
  436. {
  437. TOKEN_USER *tkUser;
  438. DWORD tkSize;
  439. DWORD sidLength;
  440. // Call to get size information for alloc
  441. GetTokenInformation(tkHandle, TokenUser, NULL, 0, &tkSize);
  442. tkUser = (TOKEN_USER *) new BYTE[tkSize];
  443. if (NULL == tkUser)
  444. {
  445. CloseHandle(tkHandle);
  446. return E_OUTOFMEMORY;
  447. }
  448. // Now make the real call
  449. if (GetTokenInformation(tkHandle, TokenUser, tkUser, tkSize, &tkSize))
  450. {
  451. sidLength = GetLengthSid(tkUser->User.Sid);
  452. *ppSid = (PSID) new BYTE[sidLength];
  453. if (NULL != *ppSid)
  454. {
  455. memcpy(*ppSid, tkUser->User.Sid, sidLength);
  456. CloseHandle(tkHandle);
  457. delete[] (LPBYTE)(tkUser);
  458. return S_OK;
  459. }
  460. else
  461. {
  462. CloseHandle(tkHandle);
  463. delete[] (LPBYTE)(tkUser);
  464. return E_OUTOFMEMORY;
  465. }
  466. }
  467. else
  468. {
  469. delete[] (LPBYTE)(tkUser);
  470. return HRESULT_FROM_WIN32(GetLastError());
  471. }
  472. }
  473. return HRESULT_FROM_WIN32(GetLastError());
  474. }
  475. HRESULT CSecurityDescriptor::GetPrincipalSID(LPCTSTR pszPrincipal, PSID *ppSid)
  476. {
  477. HRESULT hr;
  478. LPTSTR pszRefDomain = NULL;
  479. DWORD dwDomainSize = 0;
  480. DWORD dwSidSize = 0;
  481. SID_NAME_USE snu;
  482. // Call to get size info for alloc
  483. LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu);
  484. hr = GetLastError();
  485. if (hr != ERROR_INSUFFICIENT_BUFFER)
  486. return HRESULT_FROM_WIN32(hr);
  487. pszRefDomain = new TCHAR[dwDomainSize];
  488. if (pszRefDomain == NULL)
  489. return E_OUTOFMEMORY;
  490. *ppSid = (PSID) new BYTE[dwSidSize];
  491. if (*ppSid != NULL)
  492. {
  493. if (!LookupAccountName(NULL, pszPrincipal, *ppSid, &dwSidSize, pszRefDomain, &dwDomainSize, &snu))
  494. {
  495. delete[] (LPBYTE)(*ppSid);
  496. *ppSid = NULL;
  497. delete[] pszRefDomain;
  498. return HRESULT_FROM_WIN32(GetLastError());
  499. }
  500. delete[] pszRefDomain;
  501. return S_OK;
  502. }
  503. delete[] pszRefDomain;
  504. return E_OUTOFMEMORY;
  505. }
  506. HRESULT CSecurityDescriptor::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD)
  507. {
  508. PACL pDACL = NULL;
  509. PACL pSACL = NULL;
  510. BOOL bDACLPresent, bSACLPresent;
  511. BOOL bDefaulted;
  512. PACL m_pDACL = NULL;
  513. ACCESS_ALLOWED_ACE* pACE;
  514. HRESULT hr;
  515. PSID pUserSid;
  516. PSID pGroupSid;
  517. hr = Initialize();
  518. if(FAILED(hr))
  519. return hr;
  520. // get the existing DACL.
  521. if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted))
  522. goto failed;
  523. if (bDACLPresent)
  524. {
  525. if (pDACL)
  526. {
  527. // allocate new DACL.
  528. if (NULL == (m_pDACL = (PACL) new BYTE[pDACL->AclSize]))
  529. goto failed;
  530. // initialize the DACL
  531. if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION))
  532. goto failed;
  533. // copy the ACES
  534. for (int i = 0; i < pDACL->AceCount; i++)
  535. {
  536. if (!GetAce(pDACL, i, (void **)&pACE))
  537. goto failed;
  538. if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
  539. goto failed;
  540. }
  541. if (!IsValidAcl(m_pDACL))
  542. goto failed;
  543. }
  544. // set the DACL
  545. if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted))
  546. goto failed;
  547. }
  548. // get the existing SACL.
  549. if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted))
  550. goto failed;
  551. if (bSACLPresent)
  552. {
  553. if (pSACL)
  554. {
  555. // allocate new SACL.
  556. if (NULL == (m_pSACL = (PACL) new BYTE[pSACL->AclSize]))
  557. goto failed;
  558. // initialize the SACL
  559. if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION))
  560. goto failed;
  561. // copy the ACES
  562. for (int i = 0; i < pSACL->AceCount; i++)
  563. {
  564. if (!GetAce(pSACL, i, (void **)&pACE))
  565. goto failed;
  566. if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
  567. goto failed;
  568. }
  569. if (!IsValidAcl(m_pSACL))
  570. goto failed;
  571. }
  572. // set the SACL
  573. if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted))
  574. goto failed;
  575. }
  576. if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted))
  577. goto failed;
  578. if (FAILED(SetOwner(pUserSid, bDefaulted)))
  579. goto failed;
  580. if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted))
  581. goto failed;
  582. if (FAILED(SetGroup(pGroupSid, bDefaulted)))
  583. goto failed;
  584. if (!IsValidSecurityDescriptor(m_pSD))
  585. goto failed;
  586. return hr;
  587. failed:
  588. if (m_pDACL)
  589. delete[] (LPBYTE)(m_pDACL);
  590. if (m_pSD)
  591. delete[] (LPBYTE)(m_pSD);
  592. return E_UNEXPECTED;
  593. }
  594. HRESULT CSecurityDescriptor::AttachObject(HANDLE hObject)
  595. {
  596. HRESULT hr;
  597. DWORD dwSize = 0;
  598. PSECURITY_DESCRIPTOR pSD = NULL;
  599. GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  600. DACL_SECURITY_INFORMATION, pSD, 0, &dwSize);
  601. hr = GetLastError();
  602. if (hr != ERROR_INSUFFICIENT_BUFFER)
  603. return HRESULT_FROM_WIN32(hr);
  604. pSD = (PSECURITY_DESCRIPTOR) new BYTE[dwSize];
  605. if (!GetKernelObjectSecurity(hObject, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
  606. DACL_SECURITY_INFORMATION, pSD, dwSize, &dwSize))
  607. {
  608. hr = HRESULT_FROM_WIN32(GetLastError());
  609. delete[] (LPBYTE)(pSD);
  610. return hr;
  611. }
  612. hr = Attach(pSD);
  613. delete[] (LPBYTE)(pSD);
  614. return hr;
  615. }
  616. HRESULT CSecurityDescriptor::CopyACL(PACL pDest, PACL pSrc)
  617. {
  618. ACL_SIZE_INFORMATION aclSizeInfo;
  619. LPVOID pAce;
  620. ACE_HEADER *aceHeader;
  621. if (pSrc == NULL)
  622. return S_OK;
  623. if (!GetAclInformation(pSrc, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
  624. return HRESULT_FROM_WIN32(GetLastError());
  625. // Copy all of the ACEs to the new ACL
  626. for (UINT i = 0; i < aclSizeInfo.AceCount; i++)
  627. {
  628. if (!GetAce(pSrc, i, &pAce))
  629. return HRESULT_FROM_WIN32(GetLastError());
  630. aceHeader = (ACE_HEADER *) pAce;
  631. if (!AddAce(pDest, ACL_REVISION, 0xffffffff, pAce, aceHeader->AceSize))
  632. return HRESULT_FROM_WIN32(GetLastError());
  633. }
  634. return S_OK;
  635. }
  636. HRESULT CSecurityDescriptor::AddAccessDeniedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
  637. {
  638. ACL_SIZE_INFORMATION aclSizeInfo;
  639. int aclSize;
  640. DWORD returnValue;
  641. PSID principalSID;
  642. PACL oldACL, newACL;
  643. oldACL = *ppAcl;
  644. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  645. if (FAILED(returnValue))
  646. return returnValue;
  647. aclSizeInfo.AclBytesInUse = 0;
  648. if (*ppAcl != NULL)
  649. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  650. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  651. newACL = (PACL) new BYTE[aclSize];
  652. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  653. {
  654. delete[] (LPBYTE)(principalSID);
  655. return HRESULT_FROM_WIN32(GetLastError());
  656. }
  657. if (!AddAccessDeniedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  658. {
  659. delete[] (LPBYTE)(principalSID);
  660. return HRESULT_FROM_WIN32(GetLastError());
  661. }
  662. returnValue = CopyACL(newACL, oldACL);
  663. if (FAILED(returnValue))
  664. {
  665. delete[] (LPBYTE)(principalSID);
  666. return returnValue;
  667. }
  668. *ppAcl = newACL;
  669. if (oldACL != NULL)
  670. delete[] (LPBYTE)(oldACL);
  671. delete[] (LPBYTE)(principalSID);
  672. return S_OK;
  673. }
  674. HRESULT CSecurityDescriptor::AddAccessDeniedACEToACL(PACL *ppAcl, const SecurityId *psidPrincipal, DWORD dwAccessMask)
  675. {
  676. ACL_SIZE_INFORMATION aclSizeInfo;
  677. int aclSize;
  678. DWORD returnValue;
  679. PSID principalSID;
  680. PACL oldACL, newACL;
  681. DWORD dwLen, dwIx;
  682. oldACL = *ppAcl;
  683. ASSERT(255 >= psidPrincipal->dwRidCount);
  684. dwLen = GetSidLengthRequired((UCHAR)psidPrincipal->dwRidCount);
  685. principalSID = (PSID)(new BYTE[dwLen]);
  686. if (!InitializeSid(
  687. principalSID,
  688. (PSID_IDENTIFIER_AUTHORITY)&psidPrincipal->sid,
  689. (UCHAR)psidPrincipal->dwRidCount))
  690. {
  691. delete[] (LPBYTE)principalSID;
  692. return HRESULT_FROM_WIN32(GetLastError());
  693. }
  694. for (dwIx = 0; dwIx < psidPrincipal->dwRidCount; dwIx += 1)
  695. *GetSidSubAuthority(principalSID, dwIx) = psidPrincipal->rgRids[dwIx];
  696. if (!IsValidSid(principalSID))
  697. {
  698. delete[] (LPBYTE)principalSID;
  699. return HRESULT_FROM_WIN32(GetLastError());
  700. }
  701. aclSizeInfo.AclBytesInUse = 0;
  702. if (*ppAcl != NULL)
  703. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  704. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_DENIED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  705. newACL = (PACL) new BYTE[aclSize];
  706. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  707. {
  708. delete[] (LPBYTE)(principalSID);
  709. return HRESULT_FROM_WIN32(GetLastError());
  710. }
  711. if (!AddAccessDeniedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  712. {
  713. delete[] (LPBYTE)(principalSID);
  714. return HRESULT_FROM_WIN32(GetLastError());
  715. }
  716. returnValue = CopyACL(newACL, oldACL);
  717. if (FAILED(returnValue))
  718. {
  719. delete[] (LPBYTE)(principalSID);
  720. return returnValue;
  721. }
  722. *ppAcl = newACL;
  723. if (oldACL != NULL)
  724. delete[] (LPBYTE)(oldACL);
  725. delete[] (LPBYTE)(principalSID);
  726. return S_OK;
  727. }
  728. HRESULT CSecurityDescriptor::AddAccessAllowedACEToACL(PACL *ppAcl, const SecurityId *psidPrincipal, DWORD dwAccessMask)
  729. {
  730. ACL_SIZE_INFORMATION aclSizeInfo;
  731. int aclSize;
  732. DWORD returnValue;
  733. PSID principalSID = NULL;
  734. PACL oldACL, newACL;
  735. DWORD dwLen, dwIx;
  736. oldACL = *ppAcl;
  737. ASSERT(255 >= psidPrincipal->dwRidCount);
  738. dwLen = GetSidLengthRequired((UCHAR)psidPrincipal->dwRidCount);
  739. principalSID = (PSID)(new BYTE[dwLen]);
  740. if (!InitializeSid(
  741. principalSID,
  742. (PSID_IDENTIFIER_AUTHORITY)&psidPrincipal->sid,
  743. (UCHAR)psidPrincipal->dwRidCount))
  744. {
  745. delete[] (LPBYTE)principalSID;
  746. return HRESULT_FROM_WIN32(GetLastError());
  747. }
  748. for (dwIx = 0; dwIx < psidPrincipal->dwRidCount; dwIx += 1)
  749. *GetSidSubAuthority(principalSID, dwIx) = psidPrincipal->rgRids[dwIx];
  750. if (!IsValidSid(principalSID))
  751. {
  752. delete[] (LPBYTE)principalSID;
  753. return HRESULT_FROM_WIN32(GetLastError());
  754. }
  755. aclSizeInfo.AclBytesInUse = 0;
  756. if (*ppAcl != NULL)
  757. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  758. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  759. newACL = (PACL) new BYTE[aclSize];
  760. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  761. {
  762. delete[] (LPBYTE)principalSID;
  763. return HRESULT_FROM_WIN32(GetLastError());
  764. }
  765. returnValue = CopyACL(newACL, oldACL);
  766. if (FAILED(returnValue))
  767. {
  768. delete[] (LPBYTE)principalSID;
  769. return returnValue;
  770. }
  771. if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  772. {
  773. delete[] (LPBYTE)principalSID;
  774. return HRESULT_FROM_WIN32(GetLastError());
  775. }
  776. *ppAcl = newACL;
  777. if (oldACL != NULL)
  778. delete[] (LPBYTE)(oldACL);
  779. delete[] (LPBYTE)principalSID;
  780. return S_OK;
  781. }
  782. HRESULT CSecurityDescriptor::AddAccessAllowedACEToACL(PACL *ppAcl, LPCTSTR pszPrincipal, DWORD dwAccessMask)
  783. {
  784. ACL_SIZE_INFORMATION aclSizeInfo;
  785. int aclSize;
  786. DWORD returnValue;
  787. PSID principalSID;
  788. PACL oldACL, newACL;
  789. oldACL = *ppAcl;
  790. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  791. if (FAILED(returnValue))
  792. return returnValue;
  793. aclSizeInfo.AclBytesInUse = 0;
  794. if (*ppAcl != NULL)
  795. GetAclInformation(oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  796. aclSize = aclSizeInfo.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(principalSID) - sizeof(DWORD);
  797. newACL = (PACL) new BYTE[aclSize];
  798. if (!InitializeAcl(newACL, aclSize, ACL_REVISION))
  799. {
  800. delete[] (LPBYTE)(principalSID);
  801. return HRESULT_FROM_WIN32(GetLastError());
  802. }
  803. returnValue = CopyACL(newACL, oldACL);
  804. if (FAILED(returnValue))
  805. {
  806. delete[] (LPBYTE)(principalSID);
  807. return returnValue;
  808. }
  809. if (!AddAccessAllowedAce(newACL, ACL_REVISION2, dwAccessMask, principalSID))
  810. {
  811. delete[] (LPBYTE)(principalSID);
  812. return HRESULT_FROM_WIN32(GetLastError());
  813. }
  814. *ppAcl = newACL;
  815. if (oldACL != NULL)
  816. delete[] (LPBYTE)(oldACL);
  817. delete[] (LPBYTE)(principalSID);
  818. return S_OK;
  819. }
  820. HRESULT CSecurityDescriptor::RemovePrincipalFromACL(PACL pAcl, LPCTSTR pszPrincipal)
  821. {
  822. ACL_SIZE_INFORMATION aclSizeInfo;
  823. ULONG i;
  824. LPVOID ace;
  825. ACCESS_ALLOWED_ACE *accessAllowedAce;
  826. ACCESS_DENIED_ACE *accessDeniedAce;
  827. SYSTEM_AUDIT_ACE *systemAuditAce;
  828. PSID principalSID;
  829. DWORD returnValue;
  830. ACE_HEADER *aceHeader;
  831. returnValue = GetPrincipalSID(pszPrincipal, &principalSID);
  832. if (FAILED(returnValue))
  833. return returnValue;
  834. GetAclInformation(pAcl, (LPVOID) &aclSizeInfo, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
  835. for (i = 0; i < aclSizeInfo.AceCount; i++)
  836. {
  837. if (!GetAce(pAcl, i, &ace))
  838. {
  839. delete[] (LPBYTE)(principalSID);
  840. return HRESULT_FROM_WIN32(GetLastError());
  841. }
  842. aceHeader = (ACE_HEADER *) ace;
  843. if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE)
  844. {
  845. accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace;
  846. if (EqualSid(principalSID, (PSID) &accessAllowedAce->SidStart))
  847. {
  848. DeleteAce(pAcl, i);
  849. delete[] (LPBYTE)(principalSID);
  850. return S_OK;
  851. }
  852. } else
  853. if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE)
  854. {
  855. accessDeniedAce = (ACCESS_DENIED_ACE *) ace;
  856. if (EqualSid(principalSID, (PSID) &accessDeniedAce->SidStart))
  857. {
  858. DeleteAce(pAcl, i);
  859. delete[] (LPBYTE)(principalSID);
  860. return S_OK;
  861. }
  862. } else
  863. if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE)
  864. {
  865. systemAuditAce = (SYSTEM_AUDIT_ACE *) ace;
  866. if (EqualSid(principalSID, (PSID) &systemAuditAce->SidStart))
  867. {
  868. DeleteAce(pAcl, i);
  869. delete[] (LPBYTE)(principalSID);
  870. return S_OK;
  871. }
  872. }
  873. }
  874. delete[] (LPBYTE)(principalSID);
  875. return S_OK;
  876. }
  877. HRESULT CSecurityDescriptor::SetPrivilege(LPCTSTR privilege, BOOL bEnable, HANDLE hToken)
  878. {
  879. HRESULT hr;
  880. TOKEN_PRIVILEGES tpPrevious;
  881. TOKEN_PRIVILEGES tp;
  882. DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
  883. LUID luid;
  884. // if no token specified open process token
  885. if (hToken == 0)
  886. {
  887. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  888. {
  889. hr = HRESULT_FROM_WIN32(GetLastError());
  890. _ASSERTE(FALSE);
  891. return hr;
  892. }
  893. }
  894. if (!LookupPrivilegeValue(NULL, privilege, &luid ))
  895. {
  896. hr = HRESULT_FROM_WIN32(GetLastError());
  897. _ASSERTE(FALSE);
  898. return hr;
  899. }
  900. tp.PrivilegeCount = 1;
  901. tp.Privileges[0].Luid = luid;
  902. tp.Privileges[0].Attributes = 0;
  903. if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious))
  904. {
  905. hr = HRESULT_FROM_WIN32(GetLastError());
  906. _ASSERTE(FALSE);
  907. return hr;
  908. }
  909. tpPrevious.PrivilegeCount = 1;
  910. tpPrevious.Privileges[0].Luid = luid;
  911. if (bEnable)
  912. tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
  913. else
  914. tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED & tpPrevious.Privileges[0].Attributes);
  915. if (!AdjustTokenPrivileges(hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL))
  916. {
  917. hr = HRESULT_FROM_WIN32(GetLastError());
  918. _ASSERTE(FALSE);
  919. return hr;
  920. }
  921. return S_OK;
  922. }
  923. CSecurityDescriptor::operator LPSECURITY_ATTRIBUTES()
  924. {
  925. m_saAttrs.nLength = sizeof (m_saAttrs);
  926. m_saAttrs.lpSecurityDescriptor = m_pSD;
  927. m_saAttrs.bInheritHandle = m_fInheritance;
  928. return (&m_saAttrs);
  929. };