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.

969 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: var2sec.cxx
  7. //
  8. // Contents:
  9. //
  10. // Functions:
  11. //
  12. // History: 25-Apr-97 KrishnaG Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "iis.hxx"
  16. #pragma hdrstop
  17. HRESULT
  18. ConvertSecurityDescriptorToSecDes(
  19. IADsSecurityDescriptor FAR * pSecDes,
  20. PSECURITY_DESCRIPTOR * ppSecurityDescriptor,
  21. PDWORD pdwSDLength
  22. )
  23. {
  24. HRESULT hr = S_OK;
  25. SECURITY_DESCRIPTOR AbsoluteSD;
  26. PSECURITY_DESCRIPTOR pRelative = NULL;
  27. BOOL Defaulted = FALSE;
  28. BOOL DaclPresent = FALSE;
  29. BOOL SaclPresent = FALSE;
  30. BOOL fDaclDefaulted = FALSE;
  31. BOOL fSaclDefaulted = FALSE;
  32. BOOL fOwnerDefaulted = FALSE;
  33. BOOL fGroupDefaulted = FALSE;
  34. PSID pOwnerSid = NULL;
  35. PSID pGroupSid = NULL;
  36. PACL pDacl = NULL;
  37. PACL pSacl = NULL;
  38. DWORD dwSDLength = 0;
  39. DWORD dwRet = 0;
  40. BOOL dwStatus = 0;
  41. LONG lControlFlags = 0;
  42. SECURITY_DESCRIPTOR_CONTROL dwControlFlags = 0;
  43. SECURITY_DESCRIPTOR_CONTROL dwControlMask =
  44. SE_DACL_AUTO_INHERIT_REQ | SE_DACL_AUTO_INHERITED |
  45. SE_DACL_PROTECTED | SE_SACL_AUTO_INHERIT_REQ |
  46. SE_SACL_AUTO_INHERITED | SE_SACL_PROTECTED;
  47. //
  48. // Initialize *pSizeSD = 0;
  49. //
  50. dwRet = InitializeSecurityDescriptor (
  51. &AbsoluteSD,
  52. SECURITY_DESCRIPTOR_REVISION1
  53. );
  54. if (!dwRet) {
  55. hr = E_FAIL;
  56. BAIL_ON_FAILURE(hr);
  57. }
  58. hr = pSecDes->get_Control(&lControlFlags);
  59. BAIL_ON_FAILURE(hr);
  60. dwControlFlags = dwControlMask & (SECURITY_DESCRIPTOR_CONTROL)lControlFlags;
  61. dwStatus = SetSecurityDescriptorControl(
  62. &AbsoluteSD,
  63. dwControlMask,
  64. dwControlFlags
  65. );
  66. if (!dwStatus) {
  67. hr = HRESULT_FROM_WIN32(GetLastError());
  68. BAIL_ON_FAILURE(hr);
  69. }
  70. hr = GetOwnerSecurityIdentifier(
  71. pSecDes,
  72. &pOwnerSid,
  73. &fOwnerDefaulted
  74. );
  75. BAIL_ON_FAILURE(hr);
  76. dwStatus = SetSecurityDescriptorOwner(
  77. &AbsoluteSD,
  78. pOwnerSid,
  79. fOwnerDefaulted
  80. );
  81. if (!dwStatus) {
  82. hr = HRESULT_FROM_WIN32(GetLastError());
  83. BAIL_ON_FAILURE(hr);
  84. }
  85. hr = GetGroupSecurityIdentifier(
  86. pSecDes,
  87. &pGroupSid,
  88. &fGroupDefaulted
  89. );
  90. BAIL_ON_FAILURE(hr);
  91. dwStatus = SetSecurityDescriptorGroup(
  92. &AbsoluteSD,
  93. pGroupSid,
  94. fGroupDefaulted
  95. );
  96. if (!dwStatus) {
  97. hr = HRESULT_FROM_WIN32(GetLastError());
  98. BAIL_ON_FAILURE(hr);
  99. }
  100. hr = GetDacl(
  101. pSecDes,
  102. &pDacl,
  103. &fDaclDefaulted
  104. );
  105. BAIL_ON_FAILURE(hr);
  106. if (pDacl || fDaclDefaulted) {
  107. DaclPresent = TRUE;
  108. }
  109. dwStatus = SetSecurityDescriptorDacl(
  110. &AbsoluteSD,
  111. DaclPresent,
  112. pDacl,
  113. fDaclDefaulted
  114. );
  115. if (!dwStatus) {
  116. hr = HRESULT_FROM_WIN32(GetLastError());
  117. BAIL_ON_FAILURE(hr);
  118. }
  119. hr = GetSacl(
  120. pSecDes,
  121. &pSacl,
  122. &fSaclDefaulted
  123. );
  124. BAIL_ON_FAILURE(hr);
  125. if (pSacl || fSaclDefaulted) {
  126. SaclPresent = TRUE;
  127. }
  128. dwStatus = SetSecurityDescriptorSacl(
  129. &AbsoluteSD,
  130. SaclPresent,
  131. pSacl,
  132. fSaclDefaulted
  133. );
  134. if (!dwStatus) {
  135. hr = HRESULT_FROM_WIN32(GetLastError());
  136. BAIL_ON_FAILURE(hr);
  137. }
  138. dwSDLength = GetSecurityDescriptorLength(
  139. &AbsoluteSD
  140. );
  141. pRelative = AllocADsMem(dwSDLength);
  142. if (!pRelative) {
  143. hr = E_OUTOFMEMORY;
  144. BAIL_ON_FAILURE(hr);
  145. }
  146. if (!MakeSelfRelativeSD (&AbsoluteSD, pRelative, &dwSDLength)) {
  147. FreeADsMem(pRelative);
  148. hr = HRESULT_FROM_WIN32(GetLastError());
  149. BAIL_ON_FAILURE(hr);
  150. }
  151. *ppSecurityDescriptor = pRelative;
  152. *pdwSDLength = dwSDLength;
  153. cleanup:
  154. if (pDacl) {
  155. FreeADsMem(pDacl);
  156. }
  157. if (pSacl) {
  158. FreeADsMem(pSacl);
  159. }
  160. if (pOwnerSid) {
  161. FreeADsMem(pOwnerSid);
  162. }
  163. if (pGroupSid) {
  164. FreeADsMem(pGroupSid);
  165. }
  166. RRETURN(hr);
  167. error:
  168. if (pRelative) {
  169. FreeADsMem(pRelative);
  170. }
  171. *ppSecurityDescriptor = NULL;
  172. *pdwSDLength = 0;
  173. goto cleanup;
  174. }
  175. HRESULT
  176. GetOwnerSecurityIdentifier(
  177. IADsSecurityDescriptor FAR * pSecDes,
  178. PSID * ppSid,
  179. PBOOL pfOwnerDefaulted
  180. )
  181. {
  182. BSTR bstrOwner = NULL;
  183. DWORD dwSidSize = 0;
  184. HRESULT hr = S_OK;
  185. VARIANT_BOOL varBool = VARIANT_FALSE;
  186. hr = pSecDes->get_Owner(
  187. &bstrOwner
  188. );
  189. BAIL_ON_FAILURE(hr);
  190. hr = pSecDes->get_OwnerDefaulted(
  191. &varBool
  192. );
  193. BAIL_ON_FAILURE(hr);
  194. if (varBool == VARIANT_FALSE) {
  195. if (bstrOwner && *bstrOwner) {
  196. hr = ConvertTrusteeToSid(
  197. bstrOwner,
  198. ppSid,
  199. &dwSidSize
  200. );
  201. BAIL_ON_FAILURE(hr);
  202. *pfOwnerDefaulted = FALSE;
  203. }else {
  204. *ppSid = NULL;
  205. *pfOwnerDefaulted = FALSE;
  206. }
  207. }else {
  208. *ppSid = NULL;
  209. dwSidSize = 0;
  210. *pfOwnerDefaulted = TRUE;
  211. }
  212. error:
  213. if (bstrOwner) {
  214. ADsFreeString(bstrOwner);
  215. }
  216. RRETURN(hr);
  217. }
  218. HRESULT
  219. GetGroupSecurityIdentifier(
  220. IADsSecurityDescriptor FAR * pSecDes,
  221. PSID * ppSid,
  222. PBOOL pfGroupDefaulted
  223. )
  224. {
  225. BSTR bstrGroup = NULL;
  226. DWORD dwSidSize = 0;
  227. HRESULT hr = S_OK;
  228. VARIANT_BOOL varBool = VARIANT_FALSE;
  229. hr = pSecDes->get_Group(
  230. &bstrGroup
  231. );
  232. BAIL_ON_FAILURE(hr);
  233. hr = pSecDes->get_GroupDefaulted(
  234. &varBool
  235. );
  236. BAIL_ON_FAILURE(hr);
  237. if (varBool == VARIANT_FALSE) {
  238. if (bstrGroup && *bstrGroup) {
  239. hr = ConvertTrusteeToSid(
  240. bstrGroup,
  241. ppSid,
  242. &dwSidSize
  243. );
  244. BAIL_ON_FAILURE(hr);
  245. *pfGroupDefaulted = FALSE;
  246. }else {
  247. *ppSid = NULL;
  248. *pfGroupDefaulted = FALSE;
  249. }
  250. }else {
  251. *ppSid = NULL;
  252. dwSidSize = 0;
  253. *pfGroupDefaulted = TRUE;
  254. }
  255. error:
  256. if (bstrGroup) {
  257. ADsFreeString(bstrGroup);
  258. }
  259. RRETURN(hr);
  260. }
  261. HRESULT
  262. GetDacl(
  263. IADsSecurityDescriptor FAR * pSecDes,
  264. PACL * ppDacl,
  265. PBOOL pfDaclDefaulted
  266. )
  267. {
  268. IADsAccessControlList FAR * pDiscAcl = NULL;
  269. IDispatch FAR * pDispatch = NULL;
  270. HRESULT hr = S_OK;
  271. VARIANT_BOOL varBool = VARIANT_FALSE;
  272. hr = pSecDes->get_DaclDefaulted(
  273. &varBool
  274. );
  275. BAIL_ON_FAILURE(hr);
  276. if (varBool == VARIANT_FALSE) {
  277. *pfDaclDefaulted = FALSE;
  278. }else {
  279. *pfDaclDefaulted = TRUE;
  280. }
  281. hr = pSecDes->get_DiscretionaryAcl(
  282. &pDispatch
  283. );
  284. BAIL_ON_FAILURE(hr);
  285. if (!pDispatch) {
  286. *ppDacl = NULL;
  287. goto error;
  288. }
  289. hr = pDispatch->QueryInterface(
  290. IID_IADsAccessControlList,
  291. (void **)&pDiscAcl
  292. );
  293. BAIL_ON_FAILURE(hr);
  294. hr = ConvertAccessControlListToAcl(
  295. pDiscAcl,
  296. ppDacl
  297. );
  298. BAIL_ON_FAILURE(hr);
  299. error:
  300. if (pDispatch) {
  301. pDispatch->Release();
  302. }
  303. if (pDiscAcl) {
  304. pDiscAcl->Release();
  305. }
  306. RRETURN(hr);
  307. }
  308. HRESULT
  309. GetSacl(
  310. IADsSecurityDescriptor FAR * pSecDes,
  311. PACL * ppSacl,
  312. PBOOL pfSaclDefaulted
  313. )
  314. {
  315. IADsAccessControlList FAR * pSystemAcl = NULL;
  316. IDispatch FAR * pDispatch = NULL;
  317. HRESULT hr = S_OK;
  318. VARIANT_BOOL varBool = VARIANT_FALSE;
  319. hr = pSecDes->get_SaclDefaulted(
  320. &varBool
  321. );
  322. BAIL_ON_FAILURE(hr);
  323. if (varBool == VARIANT_FALSE) {
  324. *pfSaclDefaulted = FALSE;
  325. }else {
  326. *pfSaclDefaulted = TRUE;
  327. }
  328. hr = pSecDes->get_SystemAcl(
  329. &pDispatch
  330. );
  331. BAIL_ON_FAILURE(hr);
  332. if (!pDispatch) {
  333. *ppSacl = NULL;
  334. goto error;
  335. }
  336. hr = pDispatch->QueryInterface(
  337. IID_IADsAccessControlList,
  338. (void **)&pSystemAcl
  339. );
  340. BAIL_ON_FAILURE(hr);
  341. hr = ConvertAccessControlListToAcl(
  342. pSystemAcl,
  343. ppSacl
  344. );
  345. BAIL_ON_FAILURE(hr);
  346. error:
  347. if (pDispatch) {
  348. pDispatch->Release();
  349. }
  350. if (pSystemAcl) {
  351. pSystemAcl->Release();
  352. }
  353. RRETURN(hr);
  354. }
  355. HRESULT
  356. ConvertAccessControlListToAcl(
  357. IADsAccessControlList FAR * pAccessList,
  358. PACL * ppAcl
  359. )
  360. {
  361. IUnknown * pUnknown = NULL;
  362. IEnumVARIANT * pEnumerator = NULL;
  363. HRESULT hr = S_OK;
  364. DWORD i = 0;
  365. DWORD cReturned = 0;
  366. VARIANT varAce;
  367. DWORD dwAceCount = 0;
  368. IADsAccessControlEntry FAR * pAccessControlEntry = NULL;
  369. LPBYTE pTempAce = NULL;
  370. DWORD dwCount = 0;
  371. PACL pAcl = NULL;
  372. DWORD dwAclSize = 0;
  373. PACE_HEADER * ppAceHdr = NULL;
  374. DWORD dwRet = 0;
  375. BOOL bRet = 0;
  376. DWORD dwAclRevision = 0;
  377. hr = pAccessList->get_AceCount((long *)&dwAceCount);
  378. BAIL_ON_FAILURE(hr);
  379. hr = pAccessList->get__NewEnum(
  380. &pUnknown
  381. );
  382. BAIL_ON_FAILURE(hr);
  383. hr = pUnknown->QueryInterface(
  384. IID_IEnumVARIANT,
  385. (void FAR * FAR *)&pEnumerator
  386. );
  387. BAIL_ON_FAILURE(hr);
  388. ppAceHdr = (PACE_HEADER *)AllocADsMem(sizeof(PACE_HEADER)*dwAceCount);
  389. if (!ppAceHdr) {
  390. hr = E_OUTOFMEMORY;
  391. BAIL_ON_FAILURE(hr);
  392. }
  393. for (i = 0; i < dwAceCount; i++) {
  394. VariantInit(&varAce);
  395. hr = pEnumerator->Next(
  396. 1,
  397. &varAce,
  398. &cReturned
  399. );
  400. CONTINUE_ON_FAILURE(hr);
  401. hr = (V_DISPATCH(&varAce))->QueryInterface(
  402. IID_IADsAccessControlEntry,
  403. (void **)&pAccessControlEntry
  404. );
  405. CONTINUE_ON_FAILURE(hr);
  406. hr = ConvertAccessControlEntryToAce(
  407. pAccessControlEntry,
  408. &(pTempAce)
  409. );
  410. VariantClear(&varAce);
  411. if (pAccessControlEntry) {
  412. pAccessControlEntry->Release();
  413. pAccessControlEntry = NULL;
  414. }
  415. BAIL_ON_FAILURE(hr);
  416. *(ppAceHdr + dwCount) = (PACE_HEADER)pTempAce;
  417. dwCount++;
  418. }
  419. hr = ComputeTotalAclSize(ppAceHdr, dwCount, &dwAclSize);
  420. BAIL_ON_FAILURE(hr);
  421. pAcl = (PACL)AllocADsMem(dwAclSize);
  422. if (!pAcl) {
  423. hr = E_OUTOFMEMORY;
  424. BAIL_ON_FAILURE(hr);
  425. }
  426. #if 0
  427. hr = pAccessList->get_AclRevision((long *)&dwAclRevision);
  428. BAIL_ON_FAILURE(hr);
  429. #else
  430. dwAclRevision = ACL_REVISION;
  431. #endif
  432. bRet = InitializeAcl(
  433. pAcl,
  434. dwAclSize,
  435. dwAclRevision
  436. );
  437. if (!bRet) {
  438. dwRet = GetLastError();
  439. hr = HRESULT_FROM_WIN32(dwRet);
  440. BAIL_ON_FAILURE(hr);
  441. }
  442. for (i = 0; i < dwCount; i++) {
  443. bRet = AddAce(
  444. pAcl,
  445. dwAclRevision,
  446. i,
  447. (LPBYTE)*(ppAceHdr + i),
  448. (*(ppAceHdr + i))->AceSize
  449. );
  450. if (!bRet) {
  451. dwRet = GetLastError();
  452. hr = HRESULT_FROM_WIN32(dwRet);
  453. BAIL_ON_FAILURE(hr);
  454. }
  455. }
  456. *ppAcl = pAcl;
  457. error:
  458. if (ppAceHdr) {
  459. for (i = 0; i < dwCount; i++) {
  460. if (*(ppAceHdr + i)) {
  461. FreeADsMem(*(ppAceHdr + i));
  462. }
  463. }
  464. FreeADsMem(ppAceHdr);
  465. }
  466. if (pUnknown) {
  467. pUnknown->Release();
  468. }
  469. if (pEnumerator) {
  470. pEnumerator->Release();
  471. }
  472. RRETURN(hr);
  473. }
  474. HRESULT
  475. ConvertAccessControlEntryToAce(
  476. IADsAccessControlEntry * pAccessControlEntry,
  477. LPBYTE * ppAce
  478. )
  479. {
  480. DWORD dwAceType = 0;
  481. HRESULT hr = S_OK;
  482. BSTR bstrTrustee = NULL;
  483. PSID pSid = NULL;
  484. DWORD dwSidSize = 0;
  485. DWORD dwAceFlags = 0;
  486. DWORD dwAccessMask = 0;
  487. DWORD dwAceSize = 0;
  488. LPBYTE pAce = NULL;
  489. PACCESS_MASK pAccessMask = NULL;
  490. PSID pSidAddress = NULL;
  491. PUSHORT pCompoundAceType = NULL;
  492. DWORD dwCompoundAceType = 0;
  493. PACE_HEADER pAceHeader = NULL;
  494. LPBYTE pOffset = NULL;
  495. BSTR bstrObjectTypeClsid = NULL;
  496. BSTR bstrInheritedObjectTypeClsid = NULL;
  497. GUID ObjectTypeGUID;
  498. GUID InheritedObjectTypeGUID;
  499. PULONG pFlags;
  500. DWORD dwFlags = 0;
  501. hr = pAccessControlEntry->get_AceType((LONG *)&dwAceType);
  502. BAIL_ON_FAILURE(hr);
  503. hr = pAccessControlEntry->get_Trustee(&bstrTrustee);
  504. BAIL_ON_FAILURE(hr);
  505. hr = ConvertTrusteeToSid(
  506. bstrTrustee,
  507. &pSid,
  508. &dwSidSize
  509. );
  510. BAIL_ON_FAILURE(hr);
  511. hr = pAccessControlEntry->get_AceFlags((long *)&dwAceFlags);
  512. BAIL_ON_FAILURE(hr);
  513. hr = pAccessControlEntry->get_AccessMask((long *)&dwAccessMask);
  514. BAIL_ON_FAILURE(hr);
  515. //
  516. // we will compensateby adding the entire ACE size
  517. //
  518. dwAceSize = dwSidSize - sizeof(ULONG);
  519. switch (dwAceType) {
  520. case ACCESS_ALLOWED_ACE_TYPE:
  521. dwAceSize += sizeof(ACCESS_ALLOWED_ACE);
  522. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  523. if (!pAce) {
  524. hr = E_OUTOFMEMORY;
  525. BAIL_ON_FAILURE(hr);
  526. }
  527. pAceHeader = (PACE_HEADER)pAce;
  528. pAceHeader->AceType = (UCHAR)dwAceType;
  529. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  530. pAceHeader->AceSize = (USHORT)dwAceSize;
  531. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  532. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  533. pSidAddress = (PSID)((LPBYTE)pAccessMask + sizeof(ACCESS_MASK));
  534. memcpy(pSidAddress, pSid, dwSidSize);
  535. break;
  536. case ACCESS_DENIED_ACE_TYPE:
  537. dwAceSize += sizeof(ACCESS_ALLOWED_ACE);
  538. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  539. if (!pAce) {
  540. hr = E_OUTOFMEMORY;
  541. BAIL_ON_FAILURE(hr);
  542. }
  543. pAceHeader = (PACE_HEADER)pAce;
  544. pAceHeader->AceType = (UCHAR)dwAceType;
  545. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  546. pAceHeader->AceSize = (USHORT)dwAceSize;
  547. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  548. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  549. pSidAddress = (PSID)((LPBYTE)pAccessMask + sizeof(ACCESS_MASK));
  550. memcpy(pSidAddress, pSid, dwSidSize);
  551. break;
  552. case SYSTEM_AUDIT_ACE_TYPE:
  553. dwAceSize += sizeof(ACCESS_ALLOWED_ACE);
  554. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  555. if (!pAce) {
  556. hr = E_OUTOFMEMORY;
  557. BAIL_ON_FAILURE(hr);
  558. }
  559. pAceHeader = (PACE_HEADER)pAce;
  560. pAceHeader->AceType = (UCHAR)dwAceType;
  561. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  562. pAceHeader->AceSize = (USHORT)dwAceSize;
  563. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  564. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  565. pSidAddress = (PSID)((LPBYTE)pAccessMask + sizeof(ACCESS_MASK));
  566. memcpy(pSidAddress, pSid, dwSidSize);
  567. break;
  568. case SYSTEM_ALARM_ACE_TYPE:
  569. dwAceSize += sizeof(ACCESS_ALLOWED_ACE);
  570. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  571. if (!pAce) {
  572. hr = E_OUTOFMEMORY;
  573. BAIL_ON_FAILURE(hr);
  574. }
  575. pAceHeader = (PACE_HEADER)pAce;
  576. pAceHeader->AceType = (UCHAR)dwAceType;
  577. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  578. pAceHeader->AceSize = (USHORT)dwAceSize;
  579. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  580. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  581. pSidAddress = (PSID)((LPBYTE)pAccessMask + sizeof(ACCESS_MASK));
  582. memcpy(pSidAddress, pSid, dwSidSize);
  583. break;
  584. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  585. dwAceSize += sizeof(COMPOUND_ACCESS_ALLOWED_ACE);
  586. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  587. if (!pAce) {
  588. hr = E_OUTOFMEMORY;
  589. BAIL_ON_FAILURE(hr);
  590. }
  591. pAceHeader = (PACE_HEADER)pAce;
  592. pAceHeader->AceType = (UCHAR)dwAceType;
  593. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  594. pAceHeader->AceSize = (USHORT)dwAceSize;
  595. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  596. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  597. pCompoundAceType = (PUSHORT)(pAccessMask + sizeof(ACCESS_MASK));
  598. *pCompoundAceType = (USHORT)dwCompoundAceType;
  599. //
  600. // Fill in the reserved field here.
  601. //
  602. pSidAddress = (PSID)((LPBYTE)pCompoundAceType + sizeof(DWORD));
  603. memcpy(pSidAddress, pSid, dwSidSize);
  604. break;
  605. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  606. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  607. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  608. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  609. hr = pAccessControlEntry->get_AceFlags((LONG *)&dwAceFlags);
  610. BAIL_ON_FAILURE(hr);
  611. hr = pAccessControlEntry->get_Flags((LONG *)&dwFlags);
  612. BAIL_ON_FAILURE(hr);
  613. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  614. dwAceSize += sizeof(GUID);
  615. }
  616. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  617. dwAceSize += sizeof(GUID);
  618. }
  619. hr = pAccessControlEntry->get_ObjectType(&bstrObjectTypeClsid);
  620. BAIL_ON_FAILURE(hr);
  621. hr = CLSIDFromString(bstrObjectTypeClsid, &ObjectTypeGUID);
  622. BAIL_ON_FAILURE(hr);
  623. hr = pAccessControlEntry->get_InheritedObjectType(&bstrInheritedObjectTypeClsid);
  624. BAIL_ON_FAILURE(hr);
  625. hr = CLSIDFromString(bstrInheritedObjectTypeClsid, &InheritedObjectTypeGUID);
  626. BAIL_ON_FAILURE(hr);
  627. dwAceSize += sizeof(ACCESS_ALLOWED_OBJECT_ACE);
  628. pAce = (LPBYTE)AllocADsMem(dwAceSize);
  629. if (!pAce) {
  630. hr = E_OUTOFMEMORY;
  631. BAIL_ON_FAILURE(hr);
  632. }
  633. pAceHeader = (PACE_HEADER)pAce;
  634. pAceHeader->AceType = (UCHAR)dwAceType;
  635. pAceHeader->AceFlags = (UCHAR)dwAceFlags;
  636. pAceHeader->AceSize = (USHORT)dwAceSize;
  637. pAccessMask = (PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  638. *pAccessMask = (ACCESS_MASK)dwAccessMask;
  639. //
  640. // Fill in Flags
  641. //
  642. pOffset = (LPBYTE)((LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
  643. pFlags = (PULONG)(pOffset);
  644. *pFlags = dwFlags;
  645. pOffset += sizeof(ULONG);
  646. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  647. memcpy(pOffset, &ObjectTypeGUID, sizeof(GUID));
  648. pOffset += sizeof(GUID);
  649. }
  650. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  651. memcpy(pOffset, &InheritedObjectTypeGUID, sizeof(GUID));
  652. pOffset += sizeof(GUID);
  653. }
  654. pSidAddress = (PSID)((LPBYTE)pOffset);
  655. memcpy(pSidAddress, pSid, dwSidSize);
  656. break;
  657. }
  658. *ppAce = pAce;
  659. error:
  660. if (bstrTrustee) {
  661. ADsFreeString(bstrTrustee);
  662. }
  663. if (pSid) {
  664. FreeADsMem(pSid);
  665. }
  666. RRETURN(hr);
  667. }
  668. HRESULT
  669. ComputeTotalAclSize(
  670. PACE_HEADER * ppAceHdr,
  671. DWORD dwAceCount,
  672. PDWORD pdwAclSize
  673. )
  674. {
  675. DWORD i = 0;
  676. PACE_HEADER pAceHdr = NULL;
  677. DWORD dwAceSize = 0;
  678. DWORD dwAclSize = 0;
  679. for (i = 0; i < dwAceCount; i++) {
  680. pAceHdr = *(ppAceHdr + i);
  681. dwAceSize = pAceHdr->AceSize;
  682. dwAclSize += dwAceSize;
  683. }
  684. dwAclSize += sizeof(ACL);
  685. *pdwAclSize = dwAclSize;
  686. RRETURN(S_OK);
  687. }
  688. HRESULT
  689. ConvertTrusteeToSid(
  690. BSTR bstrTrustee,
  691. PSID * ppSid,
  692. PDWORD pdwSidSize
  693. )
  694. {
  695. HRESULT hr = S_OK;
  696. BYTE Sid[MAX_PATH];
  697. DWORD dwSidSize = sizeof(Sid);
  698. DWORD dwRet = 0;
  699. WCHAR szDomainName[MAX_PATH];
  700. DWORD dwDomainSize = sizeof(szDomainName)/sizeof(WCHAR);
  701. SID_NAME_USE eUse;
  702. LPWSTR pszTrustee = (LPWSTR)bstrTrustee;
  703. PSID pSid = NULL;
  704. dwSidSize = sizeof(Sid);
  705. if ((*pszTrustee == (WCHAR)'\\') || (*pszTrustee == WCHAR('/'))){
  706. pszTrustee++;
  707. }
  708. dwRet = LookupAccountName(
  709. NULL,
  710. pszTrustee,
  711. Sid,
  712. &dwSidSize,
  713. szDomainName,
  714. &dwDomainSize,
  715. (PSID_NAME_USE)&eUse
  716. );
  717. if (!dwRet) {
  718. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  719. }
  720. pSid = AllocADsMem(dwSidSize);
  721. if (!pSid) {
  722. hr = E_OUTOFMEMORY;
  723. BAIL_ON_FAILURE(hr);
  724. }
  725. memcpy(pSid, Sid, dwSidSize);
  726. *pdwSidSize = dwSidSize;
  727. *ppSid = pSid;
  728. error:
  729. RRETURN(hr);
  730. }