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.

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