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.

1677 lines
56 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // Microsoft Windows //
  4. // Copyright (C) Microsoft Corporation, 1999. //
  5. // //
  6. // File: seia.cxx //
  7. // //
  8. // Contents: New marta rewrite functions for SetEntriesInAcl //
  9. // //
  10. // History: 4/99 KedarD Created //
  11. // //
  12. ////////////////////////////////////////////////////////////////////////////////
  13. #include <aclpch.hxx>
  14. #pragma hdrstop
  15. extern "C"
  16. {
  17. #include <stdio.h>
  18. #include <permit.h>
  19. #include <dsgetdc.h>
  20. #include <lmapibuf.h>
  21. #include <wmistr.h>
  22. #include <ntprov.hxx>
  23. #include <strings.h>
  24. #include <seopaque.h>
  25. #include <sertlp.h>
  26. #include <accctrl.h>
  27. #include <guidtables.h>
  28. }
  29. ////////////////////////////////////////////////////////////////////////////////
  30. // //
  31. // MACRO DEFINITIONS START HERE //
  32. // //
  33. ////////////////////////////////////////////////////////////////////////////////
  34. #define MARTA_SID_FOR_NAME \
  35. { \
  36. ((PKNOWN_ACE) *ppAcl)->Mask = pAccessInfo->Mask; \
  37. AceSize = RtlLengthSid(pAccessInfo->pSid); \
  38. memcpy( \
  39. ((PUCHAR) *ppAcl) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK), \
  40. (PUCHAR) pAccessInfo->pSid, \
  41. AceSize \
  42. ); \
  43. AceSize += sizeof(ACE_HEADER) + sizeof(ACCESS_MASK); \
  44. }
  45. #define MARTA_SID_FOR_SID \
  46. { \
  47. ((PKNOWN_ACE) *ppAcl)->Mask = pAccessInfo->Mask; \
  48. AceSize = RtlLengthSid((PSID) pExplicitAccess->Trustee.ptstrName); \
  49. memcpy( \
  50. ((PUCHAR) *ppAcl) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK), \
  51. (PUCHAR) pExplicitAccess->Trustee.ptstrName, \
  52. AceSize \
  53. ); \
  54. AceSize += sizeof(ACE_HEADER) + sizeof(ACCESS_MASK); \
  55. }
  56. #define MARTA_SID_AND_GUID_FOR_OBJECT_NAME \
  57. { \
  58. pObjName = (POBJECTS_AND_NAME_W) pExplicitAccess->Trustee.ptstrName;\
  59. ((PKNOWN_OBJECT_ACE) *ppAcl)->Flags = pObjName->ObjectsPresent; \
  60. ((PKNOWN_OBJECT_ACE) *ppAcl)->Mask = pAccessInfo->Mask; \
  61. AceSize = RtlLengthSid(pAccessInfo->pSid); \
  62. memcpy( \
  63. (PUCHAR) RtlObjectAceSid(*ppAcl), \
  64. (PUCHAR) pAccessInfo->pSid, \
  65. AceSize \
  66. ); \
  67. pGuid = RtlObjectAceObjectType(*ppAcl); \
  68. if (NULL != pGuid) \
  69. { \
  70. memcpy( \
  71. (PUCHAR) pGuid, \
  72. (PUCHAR) pAccessInfo->pObjectTypeGuid, \
  73. sizeof(GUID) \
  74. ); \
  75. AceSize += sizeof(GUID); \
  76. } \
  77. pGuid = RtlObjectAceInheritedObjectType(*ppAcl); \
  78. if (NULL != pGuid) \
  79. { \
  80. memcpy( \
  81. (PUCHAR) pGuid, \
  82. (PUCHAR) pAccessInfo->pInheritedObjectTypeGuid, \
  83. sizeof(GUID) \
  84. ); \
  85. AceSize += sizeof(GUID); \
  86. } \
  87. AceSize += sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);\
  88. }
  89. #define MARTA_SID_AND_GUID_FOR_OBJECT_SID \
  90. { \
  91. pObjSid = (POBJECTS_AND_SID) pExplicitAccess->Trustee.ptstrName; \
  92. ((PKNOWN_OBJECT_ACE) *ppAcl)->Flags = pObjSid->ObjectsPresent; \
  93. ((PKNOWN_OBJECT_ACE) *ppAcl)->Mask = pAccessInfo->Mask; \
  94. AceSize = RtlLengthSid(pObjSid->pSid); \
  95. memcpy( \
  96. (PUCHAR) RtlObjectAceSid(*ppAcl), \
  97. (PUCHAR) pObjSid->pSid, \
  98. AceSize \
  99. ); \
  100. pGuid = RtlObjectAceObjectType(*ppAcl); \
  101. if (NULL != pGuid) \
  102. { \
  103. memcpy( \
  104. (PUCHAR) pGuid, \
  105. (PUCHAR) &(pObjSid->ObjectTypeGuid), \
  106. sizeof(GUID) \
  107. ); \
  108. AceSize += sizeof(GUID); \
  109. } \
  110. pGuid = RtlObjectAceInheritedObjectType(*ppAcl); \
  111. if (NULL != pGuid) \
  112. { \
  113. memcpy( \
  114. (PUCHAR) pGuid, \
  115. (PUCHAR) &(pObjSid->InheritedObjectTypeGuid), \
  116. sizeof(GUID) \
  117. ); \
  118. AceSize += sizeof(GUID); \
  119. } \
  120. AceSize += sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);\
  121. }
  122. typedef struct _MARTA_ACCESS_INFO
  123. {
  124. ACCESS_MASK Mask;
  125. ULONG Size;
  126. PSID pSid;
  127. PSID pServerSid;
  128. GUID * pObjectTypeGuid;
  129. GUID * pInheritedObjectTypeGuid;
  130. } MARTA_ACCESS_INFO, *PMARTA_ACCESS_INFO;
  131. ////////////////////////////////////////////////////////////////////////////////
  132. // //
  133. // FUNCTION PROTOTYPES START HERE //
  134. // //
  135. ////////////////////////////////////////////////////////////////////////////////
  136. DWORD
  137. WINAPI
  138. AccRewriteSetEntriesInAcl(
  139. IN ULONG cCountOfExplicitEntries,
  140. IN PEXPLICIT_ACCESS_W pListOfExplicitEntries,
  141. IN PACL OldAcl,
  142. OUT PACL * pNewAcl
  143. );
  144. BOOL
  145. MartaIsExplicitAclCanonical(
  146. IN PACL pAcl,
  147. OUT PULONG pExplicitAceCnt
  148. );
  149. DWORD
  150. MartaTrusteeSidAndGuidSize(
  151. IN PTRUSTEE_W pTrustee,
  152. IN BOOL bComputeGuidSize,
  153. OUT PSID * ppSid,
  154. OUT PULONG pSize,
  155. OUT PULONG pGuidCnt OPTIONAL
  156. );
  157. DWORD
  158. MartaAddExplicitEntryToAcl(
  159. IN OUT PUCHAR * ppAcl,
  160. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  161. IN PMARTA_ACCESS_INFO pAccessInfo
  162. );
  163. DWORD
  164. MartaGetSidFromName(
  165. IN LPWSTR pName,
  166. OUT PSID * ppSid
  167. );
  168. DWORD
  169. MartaGetGuid(
  170. IN LPWSTR pObjectName,
  171. IN SE_OBJECT_TYPE ObjectType,
  172. OUT GUID * pGuid
  173. );
  174. DWORD
  175. MartaGetExplicitAccessEntrySize(
  176. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  177. OUT PMARTA_ACCESS_INFO pAccessInfo,
  178. OUT PULONG pGuidCnt,
  179. OUT PUCHAR pAclRevision
  180. );
  181. DWORD
  182. MartaCompareAcesAndMarkMasks(
  183. IN PUCHAR pAce,
  184. IN PACCESS_MASK pAceMask,
  185. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  186. IN PMARTA_ACCESS_INFO pAccessInfo,
  187. IN BOOL bCanonical
  188. );
  189. ////////////////////////////////////////////////////////////////////////////////
  190. // //
  191. // Function: MartaAddExplicitEntryToAcl //
  192. // //
  193. // Description: Convert an explicit entry into an ace and store it in the //
  194. // acl. Update the acl pointer to the end. //
  195. // //
  196. // Arguments: //
  197. // //
  198. // [IN OUT ppAcl] Acl pointer where the ace should be stored //
  199. // //
  200. // [IN pExplicitAccess] Explicit entry to convert into an ace //
  201. // [IN pAccessInfo] Temp info associated with the explicit entry //
  202. // //
  203. // Returns: ERROR_SUCCESS if the entry could be converted into an ACE //
  204. // Appropriate failure otherwise //
  205. // //
  206. ////////////////////////////////////////////////////////////////////////////////
  207. DWORD
  208. MartaAddExplicitEntryToAcl(
  209. IN OUT PUCHAR * ppAcl,
  210. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  211. IN PMARTA_ACCESS_INFO pAccessInfo
  212. )
  213. {
  214. DWORD dwErr = ERROR_SUCCESS;
  215. ULONG AceSize = 0;
  216. ULONG SidSize = 0;
  217. UCHAR AceType = 0;
  218. UCHAR AceFlags = 0;
  219. PSID pSid = NULL;
  220. GUID * pGuid = NULL;
  221. POBJECTS_AND_SID pObjSid = NULL;
  222. POBJECTS_AND_NAME_W pObjName = NULL;
  223. if (REVOKE_ACCESS == pExplicitAccess->grfAccessMode)
  224. {
  225. return ERROR_SUCCESS;
  226. }
  227. if (FLAG_ON(pExplicitAccess->grfInheritance, INHERITED_ACE))
  228. {
  229. return ERROR_SUCCESS;
  230. }
  231. if (0 == pAccessInfo->Size)
  232. {
  233. return ERROR_SUCCESS;
  234. }
  235. if (TRUSTEE_IS_IMPERSONATE == pExplicitAccess->Trustee.MultipleTrusteeOperation)
  236. {
  237. ((PKNOWN_COMPOUND_ACE) *ppAcl)->CompoundAceType = COMPOUND_ACE_IMPERSONATION;
  238. ((PKNOWN_COMPOUND_ACE) *ppAcl)->Mask = pAccessInfo->Mask;
  239. ((PKNOWN_COMPOUND_ACE) *ppAcl)->Reserved = 0;
  240. AceSize = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(LONG);
  241. pSid = pAccessInfo->pServerSid ?
  242. pAccessInfo->pServerSid :
  243. (PSID) pExplicitAccess->Trustee.ptstrName;
  244. SidSize = RtlLengthSid(pSid);
  245. memcpy(
  246. ((PUCHAR) *ppAcl) + AceSize,
  247. (PUCHAR) pSid,
  248. SidSize
  249. );
  250. AceSize += SidSize;
  251. pSid = pAccessInfo->pSid ?
  252. pAccessInfo->pSid :
  253. (PSID) (pExplicitAccess->Trustee.pMultipleTrustee->ptstrName);
  254. SidSize = RtlLengthSid(pSid);
  255. memcpy(
  256. ((PUCHAR) *ppAcl) + AceSize,
  257. (PUCHAR) pSid,
  258. SidSize
  259. );
  260. AceSize += SidSize;
  261. CONDITIONAL_ACE_SIZE_ERROR(AceSize);
  262. ((PACE_HEADER) *ppAcl)->AceType = ACCESS_ALLOWED_COMPOUND_ACE_TYPE;
  263. ((PACE_HEADER) *ppAcl)->AceFlags = (UCHAR) pExplicitAccess->grfInheritance;
  264. ((PACE_HEADER) *ppAcl)->AceSize = (USHORT) AceSize;
  265. *ppAcl += AceSize;
  266. return ERROR_SUCCESS;
  267. }
  268. switch (pExplicitAccess->grfAccessMode)
  269. {
  270. case GRANT_ACCESS:
  271. case SET_ACCESS:
  272. AceFlags = (UCHAR) pExplicitAccess->grfInheritance;
  273. switch (pExplicitAccess->Trustee.TrusteeForm)
  274. {
  275. case TRUSTEE_IS_NAME:
  276. AceType = ACCESS_ALLOWED_ACE_TYPE;
  277. MARTA_SID_FOR_NAME
  278. break;
  279. case TRUSTEE_IS_SID:
  280. AceType = ACCESS_ALLOWED_ACE_TYPE;
  281. MARTA_SID_FOR_SID
  282. break;
  283. case TRUSTEE_IS_OBJECTS_AND_SID:
  284. AceType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
  285. MARTA_SID_AND_GUID_FOR_OBJECT_SID
  286. break;
  287. case TRUSTEE_IS_OBJECTS_AND_NAME:
  288. AceType = ACCESS_ALLOWED_OBJECT_ACE_TYPE;
  289. MARTA_SID_AND_GUID_FOR_OBJECT_NAME
  290. break;
  291. default:
  292. break;
  293. }
  294. break;
  295. case DENY_ACCESS:
  296. AceFlags = (UCHAR) pExplicitAccess->grfInheritance;
  297. switch (pExplicitAccess->Trustee.TrusteeForm)
  298. {
  299. case TRUSTEE_IS_NAME:
  300. AceType = ACCESS_DENIED_ACE_TYPE;
  301. MARTA_SID_FOR_NAME
  302. break;
  303. case TRUSTEE_IS_SID:
  304. AceType = ACCESS_DENIED_ACE_TYPE;
  305. MARTA_SID_FOR_SID
  306. break;
  307. case TRUSTEE_IS_OBJECTS_AND_SID:
  308. AceType = ACCESS_DENIED_OBJECT_ACE_TYPE;
  309. MARTA_SID_AND_GUID_FOR_OBJECT_SID
  310. break;
  311. case TRUSTEE_IS_OBJECTS_AND_NAME:
  312. AceType = ACCESS_DENIED_OBJECT_ACE_TYPE;
  313. MARTA_SID_AND_GUID_FOR_OBJECT_NAME
  314. break;
  315. default:
  316. break;
  317. }
  318. break;
  319. case SET_AUDIT_SUCCESS:
  320. AceFlags = (UCHAR) (pExplicitAccess->grfInheritance | SUCCESSFUL_ACCESS_ACE_FLAG);
  321. switch (pExplicitAccess->Trustee.TrusteeForm)
  322. {
  323. case TRUSTEE_IS_NAME:
  324. AceType = SYSTEM_AUDIT_ACE_TYPE;
  325. MARTA_SID_FOR_NAME
  326. break;
  327. case TRUSTEE_IS_SID:
  328. AceType = SYSTEM_AUDIT_ACE_TYPE;
  329. MARTA_SID_FOR_SID
  330. break;
  331. case TRUSTEE_IS_OBJECTS_AND_SID:
  332. AceType = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
  333. MARTA_SID_AND_GUID_FOR_OBJECT_SID
  334. break;
  335. case TRUSTEE_IS_OBJECTS_AND_NAME:
  336. AceType = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
  337. MARTA_SID_AND_GUID_FOR_OBJECT_NAME
  338. break;
  339. default:
  340. break;
  341. }
  342. break;
  343. case SET_AUDIT_FAILURE:
  344. AceFlags = (UCHAR) (pExplicitAccess->grfInheritance | FAILED_ACCESS_ACE_FLAG);
  345. switch (pExplicitAccess->Trustee.TrusteeForm)
  346. {
  347. case TRUSTEE_IS_NAME:
  348. AceType = SYSTEM_AUDIT_ACE_TYPE;
  349. MARTA_SID_FOR_NAME
  350. break;
  351. case TRUSTEE_IS_SID:
  352. AceType = SYSTEM_AUDIT_ACE_TYPE;
  353. MARTA_SID_FOR_SID
  354. break;
  355. case TRUSTEE_IS_OBJECTS_AND_SID:
  356. AceType = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
  357. MARTA_SID_AND_GUID_FOR_OBJECT_SID
  358. break;
  359. case TRUSTEE_IS_OBJECTS_AND_NAME:
  360. AceType = SYSTEM_AUDIT_OBJECT_ACE_TYPE;
  361. MARTA_SID_AND_GUID_FOR_OBJECT_NAME
  362. break;
  363. default:
  364. break;
  365. }
  366. break;
  367. case REVOKE_ACCESS:
  368. return ERROR_SUCCESS;
  369. default:
  370. return ERROR_SUCCESS;
  371. }
  372. CONDITIONAL_ACE_SIZE_ERROR(AceSize);
  373. ((PACE_HEADER) *ppAcl)->AceType = AceType;
  374. ((PACE_HEADER) *ppAcl)->AceFlags = AceFlags;
  375. ((PACE_HEADER) *ppAcl)->AceSize = (USHORT) AceSize;
  376. *ppAcl += AceSize;
  377. return ERROR_SUCCESS;
  378. }
  379. ////////////////////////////////////////////////////////////////////////////////
  380. // //
  381. // Function: MartaCompareAcesAndMarkMasks //
  382. // //
  383. // Description: Check if the explicit entry is supposed to make any changes //
  384. // to the ace. If so, store the change into the temp structure //
  385. // assoiciated with the ace. //
  386. // //
  387. // Arguments: //
  388. // //
  389. // [IN pAce] Ace to compare with the explict entry //
  390. // [IN pAceMask] Temp info associated with the ace //
  391. // [IN pExplicitAccess] Explicit entry //
  392. // [IN pAccessInfo] Temp info associated with the explicit entry //
  393. // [IN bCanonical] Whether the acl passed in is canonical //
  394. // //
  395. // Returns: ERROR_SUCCESS if the entry could be converted into an ACE //
  396. // Appropriate failure otherwise //
  397. // //
  398. ////////////////////////////////////////////////////////////////////////////////
  399. DWORD
  400. MartaCompareAcesAndMarkMasks(
  401. IN PUCHAR pAce,
  402. IN PACCESS_MASK pAceMask,
  403. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  404. IN PMARTA_ACCESS_INFO pAccessInfo,
  405. IN BOOL bCanonical
  406. )
  407. {
  408. ULONG SidLength = 0;
  409. DWORD ObjectsPresent = 0;
  410. GUID * pGuid = NULL;
  411. GUID * pObjectTypeGuid = NULL;
  412. GUID * pInheritedObjectTypeGuid = NULL;
  413. PSID pSid = NULL;
  414. POBJECTS_AND_SID pObjSid = NULL;
  415. POBJECTS_AND_NAME_W pObjName = NULL;
  416. ULONG AuditFlag = FAILED_ACCESS_ACE_FLAG;
  417. UCHAR AceFlags = 0;
  418. if (FLAG_ON(pExplicitAccess->grfInheritance, INHERITED_ACE))
  419. {
  420. return ERROR_SUCCESS;
  421. }
  422. if (TRUSTEE_IS_IMPERSONATE == pExplicitAccess->Trustee.MultipleTrusteeOperation)
  423. {
  424. if (ACCESS_ALLOWED_COMPOUND_ACE_TYPE != ((PACE_HEADER) pAce)->AceType)
  425. {
  426. return ERROR_SUCCESS;
  427. }
  428. pSid = pAccessInfo->pServerSid ?
  429. pAccessInfo->pServerSid :
  430. (PSID) pExplicitAccess->Trustee.ptstrName;
  431. if (!RtlEqualSid(
  432. pSid,
  433. (PSID) &(((PCOMPOUND_ACCESS_ALLOWED_ACE) pAce)->SidStart)
  434. ))
  435. {
  436. return ERROR_SUCCESS;
  437. }
  438. SidLength = RtlLengthSid(pSid);
  439. pSid = pAccessInfo->pSid ?
  440. pAccessInfo->pSid :
  441. (PSID) (pExplicitAccess->Trustee.pMultipleTrustee->ptstrName);
  442. if (!RtlEqualSid(
  443. pSid,
  444. (PSID) (((PUCHAR) &(((PCOMPOUND_ACCESS_ALLOWED_ACE) pAce)->SidStart)) + SidLength)
  445. ))
  446. {
  447. return ERROR_SUCCESS;
  448. }
  449. }
  450. else
  451. {
  452. switch (((PACE_HEADER) pAce)->AceType)
  453. {
  454. case ACCESS_ALLOWED_ACE_TYPE:
  455. case ACCESS_DENIED_ACE_TYPE:
  456. case SYSTEM_AUDIT_ACE_TYPE:
  457. case SYSTEM_ALARM_ACE_TYPE:
  458. switch (pExplicitAccess->Trustee.TrusteeForm)
  459. {
  460. case TRUSTEE_IS_SID:
  461. pSid = (PSID) pExplicitAccess->Trustee.ptstrName;
  462. break;
  463. case TRUSTEE_IS_NAME:
  464. pSid = pAccessInfo->pSid;
  465. break;
  466. default:
  467. return ERROR_SUCCESS;
  468. }
  469. if (!RtlEqualSid(
  470. pSid,
  471. (PSID) &(((PKNOWN_ACE) pAce)->SidStart)
  472. ))
  473. {
  474. return ERROR_SUCCESS;
  475. }
  476. break;
  477. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  478. return ERROR_SUCCESS;
  479. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  480. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  481. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  482. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  483. switch (pExplicitAccess->Trustee.TrusteeForm)
  484. {
  485. case TRUSTEE_IS_OBJECTS_AND_SID:
  486. pObjSid = (POBJECTS_AND_SID) pExplicitAccess->Trustee.ptstrName;
  487. ObjectsPresent = pObjSid->ObjectsPresent;
  488. pSid = pObjSid->pSid;
  489. pObjectTypeGuid = &(pObjSid->ObjectTypeGuid);
  490. pInheritedObjectTypeGuid = &(pObjSid->InheritedObjectTypeGuid);
  491. break;
  492. case TRUSTEE_IS_OBJECTS_AND_NAME:
  493. pObjName = (POBJECTS_AND_NAME_W) pExplicitAccess->Trustee.ptstrName;
  494. ObjectsPresent = pObjName->ObjectsPresent;
  495. pSid = pAccessInfo->pSid;
  496. pObjectTypeGuid = pAccessInfo->pObjectTypeGuid;
  497. pInheritedObjectTypeGuid = pAccessInfo->pInheritedObjectTypeGuid;
  498. break;
  499. default:
  500. return ERROR_SUCCESS;
  501. }
  502. if (ObjectsPresent != ((PKNOWN_OBJECT_ACE) pAce)->Flags)
  503. {
  504. return ERROR_SUCCESS;
  505. }
  506. if (!RtlEqualSid(pSid, RtlObjectAceSid(pAce)))
  507. {
  508. return ERROR_SUCCESS;
  509. }
  510. pGuid = RtlObjectAceObjectType(pAce);
  511. if (NULL != pGuid)
  512. {
  513. if ((NULL == pObjectTypeGuid) ||
  514. !RtlpIsEqualGuid(pGuid, pObjectTypeGuid))
  515. {
  516. return ERROR_SUCCESS;
  517. }
  518. }
  519. pGuid = RtlObjectAceInheritedObjectType(pAce);
  520. if (NULL != pGuid)
  521. {
  522. if ((NULL == pInheritedObjectTypeGuid) ||
  523. !RtlpIsEqualGuid(pGuid, pInheritedObjectTypeGuid))
  524. {
  525. return ERROR_SUCCESS;
  526. }
  527. }
  528. break;
  529. }
  530. }
  531. AceFlags = (((PACE_HEADER) pAce)->AceFlags) & VALID_INHERIT_FLAGS;
  532. if (pExplicitAccess->grfInheritance != AceFlags)
  533. {
  534. return ERROR_SUCCESS;
  535. }
  536. switch (pExplicitAccess->grfAccessMode)
  537. {
  538. case REVOKE_ACCESS:
  539. switch (((PACE_HEADER) pAce)->AceType)
  540. {
  541. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  542. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  543. case ACCESS_ALLOWED_ACE_TYPE:
  544. *pAceMask = 0;
  545. break;
  546. default:
  547. break;
  548. }
  549. break;
  550. case GRANT_ACCESS:
  551. switch (((PACE_HEADER) pAce)->AceType)
  552. {
  553. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  554. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  555. case ACCESS_ALLOWED_ACE_TYPE:
  556. if (TRUE == bCanonical)
  557. {
  558. *pAceMask |= pAccessInfo->Mask;
  559. pAccessInfo->Size = 0;
  560. }
  561. break;
  562. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  563. case ACCESS_DENIED_ACE_TYPE:
  564. *pAceMask &= ~pAccessInfo->Mask;
  565. break;
  566. default:
  567. return ERROR_SUCCESS;
  568. }
  569. break;
  570. case DENY_ACCESS:
  571. switch (((PACE_HEADER) pAce)->AceType)
  572. {
  573. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  574. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  575. case ACCESS_ALLOWED_ACE_TYPE:
  576. //
  577. // Do not delete existing Allow aces!
  578. //
  579. // *pAceMask &= ~pAccessInfo->Mask;
  580. //
  581. break;
  582. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  583. case ACCESS_DENIED_ACE_TYPE:
  584. if (TRUE == bCanonical)
  585. {
  586. *pAceMask |= pAccessInfo->Mask;
  587. pAccessInfo->Size = 0;
  588. }
  589. break;
  590. default:
  591. return ERROR_SUCCESS;
  592. }
  593. break;
  594. case SET_ACCESS:
  595. switch (((PACE_HEADER) pAce)->AceType)
  596. {
  597. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  598. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  599. case ACCESS_ALLOWED_ACE_TYPE:
  600. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  601. case ACCESS_DENIED_ACE_TYPE:
  602. *pAceMask = 0;
  603. break;
  604. default:
  605. return ERROR_SUCCESS;
  606. }
  607. break;
  608. case SET_AUDIT_SUCCESS:
  609. AuditFlag = SUCCESSFUL_ACCESS_ACE_FLAG;
  610. case SET_AUDIT_FAILURE:
  611. switch (((PACE_HEADER) pAce)->AceType)
  612. {
  613. case SYSTEM_AUDIT_ACE_TYPE:
  614. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  615. case SYSTEM_ALARM_ACE_TYPE:
  616. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  617. if (!FLAG_ON(((PACE_HEADER) pAce)->AceFlags, AuditFlag))
  618. {
  619. return ERROR_SUCCESS;
  620. }
  621. *pAceMask |= pAccessInfo->Mask;
  622. pAccessInfo->Size = 0;
  623. break;
  624. default:
  625. return ERROR_SUCCESS;
  626. }
  627. }
  628. return ERROR_SUCCESS;
  629. }
  630. ////////////////////////////////////////////////////////////////////////////////
  631. // //
  632. // Function: MartaGetExplicitAccessEntrySize //
  633. // //
  634. // Description: Computes the memory size in bytes for the ace for the //
  635. // explicit entry. //
  636. // //
  637. // Arguments: //
  638. // //
  639. // [IN pExplicitAccess] Explicit entry to convert into an ace //
  640. // [IN pAccessInfo] Temp info associated with the explicit entry //
  641. // //
  642. // [IN OUT pGuidCnt] Number of guid-names that have to be convrted //
  643. // to guid structs. //
  644. // //
  645. // Returns: ERROR_SUCCESS if the entry could be converted into an ACE //
  646. // Appropriate failure otherwise //
  647. // //
  648. ////////////////////////////////////////////////////////////////////////////////
  649. DWORD
  650. MartaGetExplicitAccessEntrySize(
  651. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  652. OUT PMARTA_ACCESS_INFO pAccessInfo,
  653. OUT PULONG pGuidCnt,
  654. OUT PUCHAR pAclRevision
  655. )
  656. {
  657. DWORD dwErr = ERROR_SUCCESS;
  658. ULONG SidAndGuidSize = 0;
  659. if (FLAG_ON(pExplicitAccess->grfInheritance, ~VALID_INHERIT_FLAGS))
  660. {
  661. return ERROR_INVALID_PARAMETER;
  662. }
  663. switch (pExplicitAccess->grfAccessMode)
  664. {
  665. case REVOKE_ACCESS:
  666. case DENY_ACCESS:
  667. case GRANT_ACCESS:
  668. case SET_ACCESS:
  669. case SET_AUDIT_SUCCESS:
  670. case SET_AUDIT_FAILURE:
  671. break;
  672. default:
  673. return ERROR_INVALID_PARAMETER;
  674. }
  675. if (FLAG_ON(pExplicitAccess->grfInheritance, INHERITED_ACE))
  676. {
  677. pAccessInfo->Size = 0;
  678. return ERROR_SUCCESS;
  679. }
  680. //
  681. // For an impersonate trustee, two sids contribute to the size.
  682. //
  683. if (TRUSTEE_IS_IMPERSONATE == pExplicitAccess->Trustee.MultipleTrusteeOperation)
  684. {
  685. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);
  686. dwErr = MartaTrusteeSidAndGuidSize(
  687. &(pExplicitAccess->Trustee),
  688. FALSE,
  689. &(pAccessInfo->pServerSid),
  690. &SidAndGuidSize,
  691. NULL
  692. );
  693. if (ERROR_SUCCESS != dwErr)
  694. {
  695. return dwErr;
  696. }
  697. pAccessInfo->Size += SidAndGuidSize;
  698. if (NULL == pExplicitAccess->Trustee.pMultipleTrustee)
  699. {
  700. return ERROR_INVALID_PARAMETER;
  701. }
  702. dwErr = MartaTrusteeSidAndGuidSize(
  703. pExplicitAccess->Trustee.pMultipleTrustee,
  704. FALSE,
  705. &(pAccessInfo->pSid),
  706. &SidAndGuidSize,
  707. NULL
  708. );
  709. if (ERROR_SUCCESS != dwErr)
  710. {
  711. return dwErr;
  712. }
  713. pAccessInfo->Size += SidAndGuidSize;
  714. if (*pAclRevision < ACL_REVISION3)
  715. {
  716. *pAclRevision = ACL_REVISION3;
  717. }
  718. return ERROR_SUCCESS;
  719. }
  720. //
  721. // For any other type of trustee, compute the space required for the SID as
  722. // well as Guids, if any.
  723. //
  724. switch (pExplicitAccess->Trustee.TrusteeForm)
  725. {
  726. case TRUSTEE_IS_OBJECTS_AND_SID:
  727. case TRUSTEE_IS_OBJECTS_AND_NAME:
  728. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);
  729. *pAclRevision = ACL_REVISION_DS;
  730. break;
  731. case TRUSTEE_IS_SID:
  732. case TRUSTEE_IS_NAME:
  733. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK);
  734. break;
  735. default:
  736. return ERROR_INVALID_PARAMETER;
  737. }
  738. dwErr = MartaTrusteeSidAndGuidSize(
  739. &(pExplicitAccess->Trustee),
  740. TRUE,
  741. &(pAccessInfo->pSid),
  742. &SidAndGuidSize,
  743. pGuidCnt
  744. );
  745. if (ERROR_SUCCESS != dwErr)
  746. {
  747. return dwErr;
  748. }
  749. if (REVOKE_ACCESS == pExplicitAccess->grfAccessMode)
  750. {
  751. pAccessInfo->Size = 0;
  752. }
  753. else
  754. {
  755. pAccessInfo->Size += SidAndGuidSize;
  756. }
  757. return ERROR_SUCCESS;
  758. }
  759. ////////////////////////////////////////////////////////////////////////////////
  760. // //
  761. // Function: MartaIsExplicitAclCanonical //
  762. // //
  763. // Description: Determines whether the explicit part of the acl is canonical. //
  764. // Finds the first explicit allow ace. //
  765. // //
  766. // Arguments: //
  767. // //
  768. // [IN pAcl] Acl //
  769. // [OUT pExplicitAceCnt] To return the first allow explicit ace //
  770. // //
  771. // Returns: TRUE if the acl is canonical //
  772. // FALSE otherwise //
  773. // //
  774. ////////////////////////////////////////////////////////////////////////////////
  775. BOOL
  776. MartaIsExplicitAclCanonical(
  777. IN PACL pAcl,
  778. OUT PULONG pExplicitAceCnt
  779. )
  780. {
  781. USHORT j;
  782. USHORT AceCnt;
  783. PACE_HEADER pAce;
  784. *pExplicitAceCnt = 0;
  785. if ((NULL == pAcl) || (0 == pAcl->AceCount))
  786. {
  787. return TRUE;
  788. }
  789. AceCnt = pAcl->AceCount;
  790. pAce = (PACE_HEADER) FirstAce(pAcl);
  791. for (j = 0; j < AceCnt; pAce = (PACE_HEADER) NextAce(pAce))
  792. {
  793. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  794. {
  795. j++;
  796. continue;
  797. }
  798. if ((ACCESS_ALLOWED_ACE_TYPE == pAce->AceType) ||
  799. (ACCESS_ALLOWED_OBJECT_ACE_TYPE == pAce->AceType) ||
  800. (ACCESS_ALLOWED_COMPOUND_ACE_TYPE == pAce->AceType))
  801. {
  802. break;
  803. }
  804. *pExplicitAceCnt = ++j;
  805. }
  806. for (; j < AceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  807. {
  808. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  809. {
  810. continue;
  811. }
  812. if ((ACCESS_DENIED_ACE_TYPE == pAce->AceType) ||
  813. (ACCESS_DENIED_OBJECT_ACE_TYPE == pAce->AceType))
  814. {
  815. return FALSE;
  816. }
  817. }
  818. return TRUE;
  819. }
  820. ////////////////////////////////////////////////////////////////////////////////
  821. // //
  822. // Function: MartaTrusteeSidAndGuidSize //
  823. // //
  824. // Description: Compute the size for the Sid(s) and Guid(s) for the trustee. //
  825. // //
  826. // Arguments: //
  827. // //
  828. // [IN pTrustee] Trsutee for which the size has to be computed //
  829. // [IN bComputeGuidSize] Whether Guidsize should be computed //
  830. // //
  831. // [OUT ppSid] To return the Sid if trustee is "named" //
  832. // [OUT pSize] To return the size computed //
  833. // [OUT pGuidCnt] To return the number of guids //
  834. // //
  835. // Returns: ERROR_SUCCESS if Name to Sid resolution passed //
  836. // Appropriate failure otherwise //
  837. // //
  838. ////////////////////////////////////////////////////////////////////////////////
  839. DWORD
  840. MartaTrusteeSidAndGuidSize(
  841. IN PTRUSTEE_W pTrustee,
  842. IN BOOL bComputeGuidSize,
  843. OUT PSID * ppSid,
  844. OUT PULONG pSize,
  845. OUT PULONG pGuidCnt OPTIONAL
  846. )
  847. {
  848. PSID pSid = NULL;
  849. SID_NAME_USE SidType = SidTypeUnknown;
  850. DWORD dwErr = ERROR_SUCCESS;
  851. switch (pTrustee->TrusteeForm)
  852. {
  853. case TRUSTEE_IS_SID:
  854. pSid = (PSID) pTrustee->ptstrName;
  855. if ((NULL == pSid) || (!RtlValidSid(pSid)))
  856. {
  857. return ERROR_INVALID_PARAMETER;
  858. }
  859. *pSize = RtlLengthSid(pSid);
  860. break;
  861. case TRUSTEE_IS_OBJECTS_AND_SID:
  862. pSid = ((POBJECTS_AND_SID) pTrustee->ptstrName)->pSid;
  863. if ((NULL == pSid) || (!RtlValidSid(pSid)))
  864. {
  865. return ERROR_INVALID_PARAMETER;
  866. }
  867. *pSize = RtlLengthSid(pSid);
  868. if (TRUE == bComputeGuidSize)
  869. {
  870. if (FLAG_ON(((POBJECTS_AND_SID) pTrustee->ptstrName)->ObjectsPresent,
  871. ACE_OBJECT_TYPE_PRESENT))
  872. {
  873. *pSize += sizeof(GUID);
  874. }
  875. if (FLAG_ON(((POBJECTS_AND_SID) pTrustee->ptstrName)->ObjectsPresent,
  876. ACE_INHERITED_OBJECT_TYPE_PRESENT))
  877. {
  878. *pSize += sizeof(GUID);
  879. }
  880. }
  881. break;
  882. case TRUSTEE_IS_NAME:
  883. dwErr = MartaGetSidFromName(pTrustee->ptstrName, ppSid);
  884. CONDITIONAL_RETURN(dwErr);
  885. *pSize = RtlLengthSid(*ppSid);
  886. break;
  887. case TRUSTEE_IS_OBJECTS_AND_NAME:
  888. dwErr = MartaGetSidFromName(
  889. ((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ptstrName,
  890. ppSid
  891. );
  892. CONDITIONAL_RETURN(dwErr);
  893. *pSize = RtlLengthSid(*ppSid);
  894. if (TRUE == bComputeGuidSize)
  895. {
  896. if (FLAG_ON(((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ObjectsPresent,
  897. ACE_OBJECT_TYPE_PRESENT))
  898. {
  899. *pSize += sizeof(GUID);
  900. (*pGuidCnt)++;
  901. }
  902. if (FLAG_ON(((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ObjectsPresent,
  903. ACE_INHERITED_OBJECT_TYPE_PRESENT))
  904. {
  905. *pSize += sizeof(GUID);
  906. (*pGuidCnt)++;
  907. }
  908. }
  909. break;
  910. default:
  911. return ERROR_NONE_MAPPED;
  912. }
  913. return ERROR_SUCCESS;
  914. }
  915. ////////////////////////////////////////////////////////////////////////////////
  916. // //
  917. // Function: MartaGetSidFromName //
  918. // //
  919. // Description: Resolves a given Name to Sid. //
  920. // //
  921. // Arguments: //
  922. // //
  923. // [IN pName] Name to be resolved //
  924. // [OUT ppSid] To return the Sid for the trustee //
  925. // //
  926. // Returns: ERROR_SUCCESS if Name to Sid resolution passed //
  927. // Appropriate failure otherwise //
  928. // //
  929. ////////////////////////////////////////////////////////////////////////////////
  930. DWORD
  931. MartaGetSidFromName(
  932. IN LPWSTR pName,
  933. OUT PSID * ppSid
  934. )
  935. {
  936. #define MARTA_DEFAULT_SID_SIZE 64
  937. #define MARTA_DEFAULT_DOMAIN_SIZE 256
  938. WCHAR DomainBuffer[MARTA_DEFAULT_DOMAIN_SIZE];
  939. ULONG SidSize = MARTA_DEFAULT_SID_SIZE;
  940. ULONG DomainSize = MARTA_DEFAULT_DOMAIN_SIZE;
  941. LPWSTR Domain = (LPWSTR) DomainBuffer;
  942. SID_NAME_USE SidNameUse = SidTypeUnknown;
  943. DWORD dwErr = ERROR_SUCCESS;
  944. if (NULL == ppSid)
  945. {
  946. return ERROR_INVALID_PARAMETER;
  947. }
  948. if(0 == _wcsicmp(pName, L"CURRENT_USER"))
  949. {
  950. HANDLE TokenHandle;
  951. dwErr = GetCurrentToken(&TokenHandle);
  952. if(dwErr != ERROR_SUCCESS)
  953. {
  954. return dwErr;
  955. }
  956. dwErr = AccGetSidFromToken(
  957. NULL,
  958. TokenHandle,
  959. TokenUser,
  960. ppSid
  961. );
  962. CloseHandle(TokenHandle);
  963. return dwErr;
  964. }
  965. *ppSid = (PSID) AccAlloc(SidSize);
  966. if(NULL == *ppSid)
  967. {
  968. return ERROR_NOT_ENOUGH_MEMORY;
  969. }
  970. if(!LookupAccountName(
  971. NULL,
  972. pName,
  973. *ppSid,
  974. &SidSize,
  975. Domain,
  976. &DomainSize,
  977. &SidNameUse))
  978. {
  979. dwErr = GetLastError();
  980. if(dwErr == ERROR_INSUFFICIENT_BUFFER)
  981. {
  982. dwErr = ERROR_SUCCESS;
  983. if (SidSize > MARTA_DEFAULT_SID_SIZE)
  984. {
  985. AccFree(*ppSid);
  986. *ppSid = (PSID) AccAlloc(SidSize);
  987. if (*ppSid == NULL)
  988. {
  989. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  990. goto End;
  991. }
  992. }
  993. if(DomainSize > MARTA_DEFAULT_DOMAIN_SIZE)
  994. {
  995. Domain = (LPWSTR) AccAlloc(DomainSize * sizeof(WCHAR));
  996. if (NULL == Domain)
  997. {
  998. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  999. goto End;
  1000. }
  1001. if(!LookupAccountName(
  1002. NULL,
  1003. pName,
  1004. *ppSid,
  1005. &SidSize,
  1006. Domain,
  1007. &DomainSize,
  1008. &SidNameUse))
  1009. {
  1010. dwErr = GetLastError();
  1011. goto End;
  1012. }
  1013. }
  1014. }
  1015. }
  1016. End:
  1017. if (Domain != (LPWSTR) DomainBuffer)
  1018. {
  1019. AccFree(Domain);
  1020. }
  1021. if (ERROR_SUCCESS != dwErr)
  1022. {
  1023. if (NULL != *ppSid)
  1024. {
  1025. AccFree(*ppSid);
  1026. *ppSid = NULL;
  1027. }
  1028. }
  1029. return dwErr;
  1030. }
  1031. ////////////////////////////////////////////////////////////////////////////////
  1032. // //
  1033. // Function: MartaGetGuid //
  1034. // //
  1035. // Description: Resolves a given Guid Name to a Guid struct. //
  1036. // //
  1037. // Arguments: //
  1038. // //
  1039. // [IN pObjectName] Name to be resolved //
  1040. // [IN ObjectType] Object type of the name to be resolved //
  1041. // [OUT pGuid] To return the guid //
  1042. // //
  1043. // Returns: ERROR_SUCCESS if Name to guid resolution passed //
  1044. // Appropriate failure otherwise //
  1045. // //
  1046. ////////////////////////////////////////////////////////////////////////////////
  1047. DWORD
  1048. MartaGetGuid(
  1049. IN LPWSTR pObjectName,
  1050. IN SE_OBJECT_TYPE ObjectType,
  1051. OUT GUID * pGuid
  1052. )
  1053. {
  1054. switch (ObjectType)
  1055. {
  1056. case SE_DS_OBJECT:
  1057. case SE_DS_OBJECT_ALL:
  1058. break;
  1059. default:
  1060. return ERROR_INVALID_PARAMETER;
  1061. }
  1062. return MartaConvertNameToGuid[ObjectType](
  1063. pObjectName,
  1064. pGuid
  1065. );
  1066. }
  1067. ////////////////////////////////////////////////////////////////////////////////
  1068. // //
  1069. // Function: AccRewriteSetEntriesInAcl //
  1070. // //
  1071. // Description: Resolves a given Name to Sid. //
  1072. // //
  1073. // Arguments: //
  1074. // //
  1075. // [IN cCountOfExplicitEntries] Number of items in list //
  1076. // [IN pListOfExplicitEntries] List of entries to be added //
  1077. // [IN OldAcl] The old acl to add the entries to //
  1078. // [OUT pNewAcl] To return the new acl //
  1079. // //
  1080. // Returns: ERROR_SUCCESS if everything passed //
  1081. // Appropriate failure otherwise //
  1082. // //
  1083. ////////////////////////////////////////////////////////////////////////////////
  1084. DWORD
  1085. WINAPI
  1086. AccRewriteSetEntriesInAcl(
  1087. IN ULONG cCountOfExplicitEntries,
  1088. IN PEXPLICIT_ACCESS_W pListOfExplicitEntries,
  1089. IN PACL OldAcl,
  1090. OUT PACL * pNewAcl
  1091. )
  1092. {
  1093. PMARTA_ACCESS_INFO pAccessInfo = NULL;
  1094. PACCESS_MASK pAceMaskInfo = NULL;
  1095. PACE_HEADER pAce = NULL;
  1096. GUID * pGuid = NULL;
  1097. GUID * pCurrentGuid = NULL;
  1098. POBJECTS_AND_NAME_W pObjName = NULL;
  1099. PUCHAR pAcl = NULL;
  1100. USHORT OldAceCnt = 0;
  1101. USHORT NewAceCnt = 0;
  1102. ULONG ExplicitAceCnt = 0;
  1103. ULONG NewAclSize = sizeof(ACL);
  1104. BOOL bCanonical = TRUE;
  1105. DWORD dwErr = ERROR_SUCCESS;
  1106. ULONG i = 0;
  1107. ULONG j = 0;
  1108. ULONG GuidCnt = 0;
  1109. ULONG ObjectsPresent = 0;
  1110. UCHAR AclRevision = ACL_REVISION;
  1111. if ((NULL == pNewAcl) || ((NULL != OldAcl) && (!RtlValidAcl(OldAcl))))
  1112. {
  1113. return ERROR_INVALID_PARAMETER;
  1114. }
  1115. *pNewAcl = NULL;
  1116. //
  1117. // If the number of entries to be added is zero then make a copy of the Old
  1118. // Acl as it is. Do not try to convert it into Canonical form if it's not.
  1119. //
  1120. if (0 == cCountOfExplicitEntries)
  1121. {
  1122. if (NULL != OldAcl)
  1123. {
  1124. *pNewAcl = (PACL) AccAlloc(OldAcl->AclSize);
  1125. if (NULL == *pNewAcl)
  1126. {
  1127. return ERROR_NOT_ENOUGH_MEMORY;
  1128. }
  1129. memcpy((PUCHAR) *pNewAcl, (PUCHAR) OldAcl, OldAcl->AclSize);
  1130. }
  1131. return ERROR_SUCCESS;
  1132. }
  1133. //
  1134. // Canonical acls processing will be done as in the past.
  1135. // Note: We now support non-canonical acls as well..
  1136. //
  1137. bCanonical = MartaIsExplicitAclCanonical(OldAcl, &ExplicitAceCnt);
  1138. //
  1139. // The Mask for all the aces is stored in a pAceMaskInfo and modified as
  1140. // dictated by the ExplicitAccess entries.
  1141. //
  1142. if (NULL != OldAcl)
  1143. {
  1144. OldAceCnt = OldAcl->AceCount;
  1145. NewAclSize = OldAcl->AclSize;
  1146. NewAceCnt = OldAceCnt;
  1147. pAceMaskInfo = (PACCESS_MASK) AccAlloc(sizeof(ACCESS_MASK) * OldAceCnt);
  1148. if (NULL == pAceMaskInfo)
  1149. {
  1150. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1151. goto End;
  1152. }
  1153. AclRevision = OldAcl->AclRevision;
  1154. }
  1155. //
  1156. // Note: cCountOfExplicitEntries is non-zero at this point.
  1157. //
  1158. pAccessInfo = (PMARTA_ACCESS_INFO) AccAlloc(sizeof(MARTA_ACCESS_INFO) * cCountOfExplicitEntries);
  1159. if (NULL == pAccessInfo)
  1160. {
  1161. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1162. goto End;
  1163. }
  1164. //
  1165. // Initialize the temp structures for the acl and the explicit entries.
  1166. //
  1167. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1168. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1169. {
  1170. pAceMaskInfo[j] = ((PKNOWN_ACE) pAce)->Mask;
  1171. }
  1172. for (i = 0; i < cCountOfExplicitEntries; i++)
  1173. {
  1174. pAccessInfo[i].pServerSid = NULL;
  1175. pAccessInfo[i].pSid = NULL;
  1176. pAccessInfo[i].pObjectTypeGuid = NULL;
  1177. pAccessInfo[i].pInheritedObjectTypeGuid = NULL;
  1178. pAccessInfo[i].Mask = pListOfExplicitEntries[i].grfAccessPermissions;
  1179. }
  1180. //
  1181. // Compute the size required to add this explicit entry to the acl.
  1182. //
  1183. for (i = 0; i < cCountOfExplicitEntries; i++)
  1184. {
  1185. dwErr = MartaGetExplicitAccessEntrySize(
  1186. pListOfExplicitEntries + i,
  1187. pAccessInfo + i,
  1188. &GuidCnt,
  1189. &AclRevision
  1190. );
  1191. CONDITIONAL_EXIT(dwErr, End);
  1192. }
  1193. //
  1194. // For TRUSTEE_IS_OBJECTS_AND_NAME, resolve the GuidNames to Guids and store
  1195. // them in the temp structure.
  1196. //
  1197. if (0 != GuidCnt)
  1198. {
  1199. pGuid = pCurrentGuid = (GUID *) AccAlloc(sizeof(GUID) * GuidCnt);
  1200. if (NULL == pGuid)
  1201. {
  1202. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1203. goto End;
  1204. }
  1205. for (i = 0; i < cCountOfExplicitEntries; i++)
  1206. {
  1207. pObjName = (POBJECTS_AND_NAME_W) pListOfExplicitEntries[i].Trustee.ptstrName;
  1208. ObjectsPresent = pObjName->ObjectsPresent;
  1209. if (FLAG_ON(ObjectsPresent, ACE_OBJECT_TYPE_PRESENT))
  1210. {
  1211. dwErr = MartaGetGuid(
  1212. pObjName->ObjectTypeName,
  1213. pObjName->ObjectType,
  1214. pCurrentGuid
  1215. );
  1216. CONDITIONAL_EXIT(dwErr, End);
  1217. pAccessInfo[i].pObjectTypeGuid = pCurrentGuid++;
  1218. }
  1219. if (FLAG_ON(ObjectsPresent, ACE_INHERITED_OBJECT_TYPE_PRESENT))
  1220. {
  1221. dwErr = MartaGetGuid(
  1222. pObjName->InheritedObjectTypeName,
  1223. pObjName->ObjectType,
  1224. pCurrentGuid
  1225. );
  1226. CONDITIONAL_EXIT(dwErr, End);
  1227. pAccessInfo[i].pInheritedObjectTypeGuid = pCurrentGuid++;
  1228. }
  1229. }
  1230. }
  1231. //
  1232. // Compute the effect of explict entries added on the exisiting acl.
  1233. // The size of an explicit entry will be set to zero if the entry will be
  1234. // absorbed by some existing ace.
  1235. // The Mask for an ace will be set to zero if the AceMask flags have been
  1236. // nulled out by explicit entries.
  1237. //
  1238. for (i = 0; i < cCountOfExplicitEntries; i++)
  1239. {
  1240. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1241. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1242. {
  1243. dwErr = MartaCompareAcesAndMarkMasks(
  1244. (PUCHAR) pAce,
  1245. pAceMaskInfo + j,
  1246. pListOfExplicitEntries + i,
  1247. pAccessInfo + i,
  1248. bCanonical
  1249. );
  1250. CONDITIONAL_EXIT(dwErr, End);
  1251. }
  1252. }
  1253. //
  1254. // Compute the size required for the new acl and the number of aces in it.
  1255. //
  1256. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1257. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1258. {
  1259. if (0 == pAceMaskInfo[j])
  1260. {
  1261. NewAclSize -= pAce->AceSize;
  1262. NewAceCnt--;
  1263. }
  1264. }
  1265. for (i = 0; i < cCountOfExplicitEntries; i++)
  1266. {
  1267. if (0 != pAccessInfo[i].Size)
  1268. {
  1269. NewAclSize += pAccessInfo[i].Size;
  1270. NewAceCnt++;
  1271. }
  1272. }
  1273. *pNewAcl = (PACL) AccAlloc(NewAclSize);
  1274. if (NULL == *pNewAcl)
  1275. {
  1276. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1277. goto End;
  1278. }
  1279. if (FALSE == InitializeAcl(*pNewAcl, NewAclSize, AclRevision))
  1280. {
  1281. dwErr = GetLastError();
  1282. goto End;
  1283. }
  1284. (*pNewAcl)->AceCount = NewAceCnt;
  1285. pAcl = ((PUCHAR) *pNewAcl) + sizeof(ACL);
  1286. for (i = 0; i < cCountOfExplicitEntries; i++)
  1287. {
  1288. //
  1289. // Add all the DENY ACES to the ACL.
  1290. //
  1291. switch (pListOfExplicitEntries[i].grfAccessMode)
  1292. {
  1293. case DENY_ACCESS:
  1294. case SET_AUDIT_SUCCESS:
  1295. case SET_AUDIT_FAILURE:
  1296. dwErr = MartaAddExplicitEntryToAcl(
  1297. &pAcl,
  1298. pListOfExplicitEntries + i,
  1299. pAccessInfo + i
  1300. );
  1301. CONDITIONAL_EXIT(dwErr, End);
  1302. break;
  1303. default:
  1304. break;
  1305. }
  1306. }
  1307. //
  1308. // Copy the explicit aces from the OldAcl that have not been invalidated by
  1309. // the new Aces added.
  1310. // Inherited aces will be copied afterthe explict ones have been copied.
  1311. //
  1312. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1313. for (j = 0; j < ExplicitAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1314. {
  1315. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1316. {
  1317. continue;
  1318. }
  1319. if (0 != pAceMaskInfo[j])
  1320. {
  1321. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1322. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1323. pAcl += pAce->AceSize;
  1324. }
  1325. }
  1326. //
  1327. // Add all the NON-DENY ACES to the ACL.
  1328. // DENY aces have already been added.
  1329. //
  1330. // If the ACL was canonical then follow the old behavior i.e. add the
  1331. // remaining explicit entries to the beginning of the "allowed" acl.
  1332. // Otherwise, add the ACEs to the end of the explicit part of the ACL.
  1333. //
  1334. if (FALSE == bCanonical)
  1335. {
  1336. for (; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1337. {
  1338. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1339. {
  1340. continue;
  1341. }
  1342. if (0 != pAceMaskInfo[j])
  1343. {
  1344. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1345. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1346. pAcl += pAce->AceSize;
  1347. }
  1348. }
  1349. for (i = 0; i < cCountOfExplicitEntries; i++)
  1350. {
  1351. switch (pListOfExplicitEntries[i].grfAccessMode)
  1352. {
  1353. case GRANT_ACCESS:
  1354. case SET_ACCESS:
  1355. dwErr = MartaAddExplicitEntryToAcl(
  1356. &pAcl,
  1357. pListOfExplicitEntries + i,
  1358. pAccessInfo + i
  1359. );
  1360. CONDITIONAL_EXIT(dwErr, End);
  1361. break;
  1362. default:
  1363. break;
  1364. }
  1365. }
  1366. }
  1367. else
  1368. {
  1369. for (i = 0; i < cCountOfExplicitEntries; i++)
  1370. {
  1371. switch (pListOfExplicitEntries[i].grfAccessMode)
  1372. {
  1373. case GRANT_ACCESS:
  1374. case SET_ACCESS:
  1375. dwErr = MartaAddExplicitEntryToAcl(
  1376. &pAcl,
  1377. pListOfExplicitEntries + i,
  1378. pAccessInfo + i
  1379. );
  1380. CONDITIONAL_EXIT(dwErr, End);
  1381. break;
  1382. default:
  1383. break;
  1384. }
  1385. }
  1386. for (; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1387. {
  1388. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1389. {
  1390. continue;
  1391. }
  1392. if (0 != pAceMaskInfo[j])
  1393. {
  1394. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1395. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1396. pAcl += pAce->AceSize;
  1397. }
  1398. }
  1399. }
  1400. //
  1401. // Add the inherited aces to the new ACL. This will reorder the ACEs so that
  1402. // the EXPLICIT ACEs precede the INHERITED ONES but will not arrange the ACL
  1403. // in canonical form if it was not to start with.
  1404. //
  1405. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1406. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1407. {
  1408. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1409. {
  1410. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1411. pAcl += pAce->AceSize;
  1412. }
  1413. }
  1414. End:
  1415. if (NULL != pAccessInfo)
  1416. {
  1417. for (i = 0; i < cCountOfExplicitEntries; i++ )
  1418. {
  1419. if (NULL != pAccessInfo[i].pServerSid)
  1420. {
  1421. AccFree(pAccessInfo[i].pServerSid);
  1422. }
  1423. if (NULL != pAccessInfo[i].pSid)
  1424. {
  1425. AccFree(pAccessInfo[i].pSid);
  1426. }
  1427. }
  1428. AccFree(pAccessInfo);
  1429. }
  1430. if (NULL != pGuid)
  1431. {
  1432. AccFree(pGuid);
  1433. }
  1434. if (NULL != pAceMaskInfo)
  1435. {
  1436. AccFree(pAceMaskInfo);
  1437. }
  1438. if (ERROR_SUCCESS != dwErr)
  1439. {
  1440. if (NULL != *pNewAcl)
  1441. {
  1442. AccFree(*pNewAcl);
  1443. *pNewAcl = NULL;
  1444. }
  1445. }
  1446. return dwErr;
  1447. }