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.

1699 lines
58 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. switch (pExplicitAccess->grfAccessMode)
  533. {
  534. case REVOKE_ACCESS:
  535. switch (((PACE_HEADER) pAce)->AceType)
  536. {
  537. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  538. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  539. case ACCESS_ALLOWED_ACE_TYPE:
  540. case SYSTEM_AUDIT_ACE_TYPE:
  541. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  542. case SYSTEM_ALARM_ACE_TYPE:
  543. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  544. *pAceMask = 0;
  545. break;
  546. default:
  547. break;
  548. }
  549. break;
  550. case GRANT_ACCESS:
  551. if (pExplicitAccess->grfInheritance != AceFlags)
  552. {
  553. return ERROR_SUCCESS;
  554. }
  555. switch (((PACE_HEADER) pAce)->AceType)
  556. {
  557. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  558. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  559. case ACCESS_ALLOWED_ACE_TYPE:
  560. if (TRUE == bCanonical)
  561. {
  562. *pAceMask |= pAccessInfo->Mask;
  563. pAccessInfo->Size = 0;
  564. }
  565. break;
  566. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  567. case ACCESS_DENIED_ACE_TYPE:
  568. *pAceMask &= ~pAccessInfo->Mask;
  569. break;
  570. default:
  571. return ERROR_SUCCESS;
  572. }
  573. break;
  574. case DENY_ACCESS:
  575. if (pExplicitAccess->grfInheritance != AceFlags)
  576. {
  577. return ERROR_SUCCESS;
  578. }
  579. switch (((PACE_HEADER) pAce)->AceType)
  580. {
  581. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  582. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  583. case ACCESS_ALLOWED_ACE_TYPE:
  584. //
  585. // Do not delete existing Allow aces!
  586. //
  587. // *pAceMask &= ~pAccessInfo->Mask;
  588. //
  589. break;
  590. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  591. case ACCESS_DENIED_ACE_TYPE:
  592. if (TRUE == bCanonical)
  593. {
  594. *pAceMask |= pAccessInfo->Mask;
  595. pAccessInfo->Size = 0;
  596. }
  597. break;
  598. default:
  599. return ERROR_SUCCESS;
  600. }
  601. break;
  602. case SET_ACCESS:
  603. switch (((PACE_HEADER) pAce)->AceType)
  604. {
  605. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  606. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  607. case ACCESS_ALLOWED_ACE_TYPE:
  608. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  609. case ACCESS_DENIED_ACE_TYPE:
  610. *pAceMask = 0;
  611. break;
  612. default:
  613. return ERROR_SUCCESS;
  614. }
  615. break;
  616. case SET_AUDIT_SUCCESS:
  617. AuditFlag = SUCCESSFUL_ACCESS_ACE_FLAG;
  618. case SET_AUDIT_FAILURE:
  619. if (pExplicitAccess->grfInheritance != AceFlags)
  620. {
  621. return ERROR_SUCCESS;
  622. }
  623. switch (((PACE_HEADER) pAce)->AceType)
  624. {
  625. case SYSTEM_AUDIT_ACE_TYPE:
  626. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  627. case SYSTEM_ALARM_ACE_TYPE:
  628. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  629. if (!FLAG_ON(((PACE_HEADER) pAce)->AceFlags, AuditFlag))
  630. {
  631. return ERROR_SUCCESS;
  632. }
  633. *pAceMask |= pAccessInfo->Mask;
  634. pAccessInfo->Size = 0;
  635. break;
  636. default:
  637. return ERROR_SUCCESS;
  638. }
  639. }
  640. return ERROR_SUCCESS;
  641. }
  642. ////////////////////////////////////////////////////////////////////////////////
  643. // //
  644. // Function: MartaGetExplicitAccessEntrySize //
  645. // //
  646. // Description: Computes the memory size in bytes for the ace for the //
  647. // explicit entry. //
  648. // //
  649. // Arguments: //
  650. // //
  651. // [IN pExplicitAccess] Explicit entry to convert into an ace //
  652. // [IN pAccessInfo] Temp info associated with the explicit entry //
  653. // //
  654. // [IN OUT pGuidCnt] Number of guid-names that have to be convrted //
  655. // to guid structs. //
  656. // //
  657. // Returns: ERROR_SUCCESS if the entry could be converted into an ACE //
  658. // Appropriate failure otherwise //
  659. // //
  660. ////////////////////////////////////////////////////////////////////////////////
  661. DWORD
  662. MartaGetExplicitAccessEntrySize(
  663. IN PEXPLICIT_ACCESS_W pExplicitAccess,
  664. OUT PMARTA_ACCESS_INFO pAccessInfo,
  665. OUT PULONG pGuidCnt,
  666. OUT PUCHAR pAclRevision
  667. )
  668. {
  669. DWORD dwErr = ERROR_SUCCESS;
  670. ULONG SidAndGuidSize = 0;
  671. if (FLAG_ON(pExplicitAccess->grfInheritance, ~VALID_INHERIT_FLAGS))
  672. {
  673. return ERROR_INVALID_PARAMETER;
  674. }
  675. switch (pExplicitAccess->grfAccessMode)
  676. {
  677. case REVOKE_ACCESS:
  678. case DENY_ACCESS:
  679. case GRANT_ACCESS:
  680. case SET_ACCESS:
  681. case SET_AUDIT_SUCCESS:
  682. case SET_AUDIT_FAILURE:
  683. break;
  684. default:
  685. return ERROR_INVALID_PARAMETER;
  686. }
  687. if (FLAG_ON(pExplicitAccess->grfInheritance, INHERITED_ACE))
  688. {
  689. pAccessInfo->Size = 0;
  690. return ERROR_SUCCESS;
  691. }
  692. //
  693. // For an impersonate trustee, two sids contribute to the size.
  694. //
  695. if (TRUSTEE_IS_IMPERSONATE == pExplicitAccess->Trustee.MultipleTrusteeOperation)
  696. {
  697. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);
  698. dwErr = MartaTrusteeSidAndGuidSize(
  699. &(pExplicitAccess->Trustee),
  700. FALSE,
  701. &(pAccessInfo->pServerSid),
  702. &SidAndGuidSize,
  703. NULL
  704. );
  705. if (ERROR_SUCCESS != dwErr)
  706. {
  707. return dwErr;
  708. }
  709. pAccessInfo->Size += SidAndGuidSize;
  710. if (NULL == pExplicitAccess->Trustee.pMultipleTrustee)
  711. {
  712. return ERROR_INVALID_PARAMETER;
  713. }
  714. dwErr = MartaTrusteeSidAndGuidSize(
  715. pExplicitAccess->Trustee.pMultipleTrustee,
  716. FALSE,
  717. &(pAccessInfo->pSid),
  718. &SidAndGuidSize,
  719. NULL
  720. );
  721. if (ERROR_SUCCESS != dwErr)
  722. {
  723. return dwErr;
  724. }
  725. pAccessInfo->Size += SidAndGuidSize;
  726. if (*pAclRevision < ACL_REVISION3)
  727. {
  728. *pAclRevision = ACL_REVISION3;
  729. }
  730. return ERROR_SUCCESS;
  731. }
  732. //
  733. // For any other type of trustee, compute the space required for the SID as
  734. // well as Guids, if any.
  735. //
  736. switch (pExplicitAccess->Trustee.TrusteeForm)
  737. {
  738. case TRUSTEE_IS_OBJECTS_AND_SID:
  739. case TRUSTEE_IS_OBJECTS_AND_NAME:
  740. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK) + sizeof(ULONG);
  741. *pAclRevision = ACL_REVISION_DS;
  742. break;
  743. case TRUSTEE_IS_SID:
  744. case TRUSTEE_IS_NAME:
  745. pAccessInfo->Size = sizeof(ACE_HEADER) + sizeof(ACCESS_MASK);
  746. break;
  747. default:
  748. return ERROR_INVALID_PARAMETER;
  749. }
  750. dwErr = MartaTrusteeSidAndGuidSize(
  751. &(pExplicitAccess->Trustee),
  752. TRUE,
  753. &(pAccessInfo->pSid),
  754. &SidAndGuidSize,
  755. pGuidCnt
  756. );
  757. if (ERROR_SUCCESS != dwErr)
  758. {
  759. return dwErr;
  760. }
  761. if (REVOKE_ACCESS == pExplicitAccess->grfAccessMode)
  762. {
  763. pAccessInfo->Size = 0;
  764. }
  765. else
  766. {
  767. pAccessInfo->Size += SidAndGuidSize;
  768. }
  769. return ERROR_SUCCESS;
  770. }
  771. ////////////////////////////////////////////////////////////////////////////////
  772. // //
  773. // Function: MartaIsExplicitAclCanonical //
  774. // //
  775. // Description: Determines whether the explicit part of the acl is canonical. //
  776. // Finds the first explicit allow ace. //
  777. // //
  778. // Arguments: //
  779. // //
  780. // [IN pAcl] Acl //
  781. // [OUT pExplicitAceCnt] To return the first allow explicit ace //
  782. // //
  783. // Returns: TRUE if the acl is canonical //
  784. // FALSE otherwise //
  785. // //
  786. ////////////////////////////////////////////////////////////////////////////////
  787. BOOL
  788. MartaIsExplicitAclCanonical(
  789. IN PACL pAcl,
  790. OUT PULONG pExplicitAceCnt
  791. )
  792. {
  793. USHORT j;
  794. USHORT AceCnt;
  795. PACE_HEADER pAce;
  796. *pExplicitAceCnt = 0;
  797. if ((NULL == pAcl) || (0 == pAcl->AceCount))
  798. {
  799. return TRUE;
  800. }
  801. AceCnt = pAcl->AceCount;
  802. pAce = (PACE_HEADER) FirstAce(pAcl);
  803. for (j = 0; j < AceCnt; pAce = (PACE_HEADER) NextAce(pAce))
  804. {
  805. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  806. {
  807. j++;
  808. continue;
  809. }
  810. if ((ACCESS_ALLOWED_ACE_TYPE == pAce->AceType) ||
  811. (ACCESS_ALLOWED_OBJECT_ACE_TYPE == pAce->AceType) ||
  812. (ACCESS_ALLOWED_COMPOUND_ACE_TYPE == pAce->AceType))
  813. {
  814. break;
  815. }
  816. *pExplicitAceCnt = ++j;
  817. }
  818. for (; j < AceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  819. {
  820. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  821. {
  822. continue;
  823. }
  824. if ((ACCESS_DENIED_ACE_TYPE == pAce->AceType) ||
  825. (ACCESS_DENIED_OBJECT_ACE_TYPE == pAce->AceType))
  826. {
  827. return FALSE;
  828. }
  829. }
  830. return TRUE;
  831. }
  832. ////////////////////////////////////////////////////////////////////////////////
  833. // //
  834. // Function: MartaTrusteeSidAndGuidSize //
  835. // //
  836. // Description: Compute the size for the Sid(s) and Guid(s) for the trustee. //
  837. // //
  838. // Arguments: //
  839. // //
  840. // [IN pTrustee] Trsutee for which the size has to be computed //
  841. // [IN bComputeGuidSize] Whether Guidsize should be computed //
  842. // //
  843. // [OUT ppSid] To return the Sid if trustee is "named" //
  844. // [OUT pSize] To return the size computed //
  845. // [OUT pGuidCnt] To return the number of guids //
  846. // //
  847. // Returns: ERROR_SUCCESS if Name to Sid resolution passed //
  848. // Appropriate failure otherwise //
  849. // //
  850. ////////////////////////////////////////////////////////////////////////////////
  851. DWORD
  852. MartaTrusteeSidAndGuidSize(
  853. IN PTRUSTEE_W pTrustee,
  854. IN BOOL bComputeGuidSize,
  855. OUT PSID * ppSid,
  856. OUT PULONG pSize,
  857. OUT PULONG pGuidCnt OPTIONAL
  858. )
  859. {
  860. PSID pSid = NULL;
  861. SID_NAME_USE SidType = SidTypeUnknown;
  862. DWORD dwErr = ERROR_SUCCESS;
  863. switch (pTrustee->TrusteeForm)
  864. {
  865. case TRUSTEE_IS_SID:
  866. pSid = (PSID) pTrustee->ptstrName;
  867. if ((NULL == pSid) || (!RtlValidSid(pSid)))
  868. {
  869. return ERROR_INVALID_PARAMETER;
  870. }
  871. *pSize = RtlLengthSid(pSid);
  872. break;
  873. case TRUSTEE_IS_OBJECTS_AND_SID:
  874. pSid = ((POBJECTS_AND_SID) pTrustee->ptstrName)->pSid;
  875. if ((NULL == pSid) || (!RtlValidSid(pSid)))
  876. {
  877. return ERROR_INVALID_PARAMETER;
  878. }
  879. *pSize = RtlLengthSid(pSid);
  880. if (TRUE == bComputeGuidSize)
  881. {
  882. if (FLAG_ON(((POBJECTS_AND_SID) pTrustee->ptstrName)->ObjectsPresent,
  883. ACE_OBJECT_TYPE_PRESENT))
  884. {
  885. *pSize += sizeof(GUID);
  886. }
  887. if (FLAG_ON(((POBJECTS_AND_SID) pTrustee->ptstrName)->ObjectsPresent,
  888. ACE_INHERITED_OBJECT_TYPE_PRESENT))
  889. {
  890. *pSize += sizeof(GUID);
  891. }
  892. }
  893. break;
  894. case TRUSTEE_IS_NAME:
  895. dwErr = MartaGetSidFromName(pTrustee->ptstrName, ppSid);
  896. CONDITIONAL_RETURN(dwErr);
  897. *pSize = RtlLengthSid(*ppSid);
  898. break;
  899. case TRUSTEE_IS_OBJECTS_AND_NAME:
  900. dwErr = MartaGetSidFromName(
  901. ((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ptstrName,
  902. ppSid
  903. );
  904. CONDITIONAL_RETURN(dwErr);
  905. *pSize = RtlLengthSid(*ppSid);
  906. if (TRUE == bComputeGuidSize)
  907. {
  908. if (FLAG_ON(((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ObjectsPresent,
  909. ACE_OBJECT_TYPE_PRESENT))
  910. {
  911. *pSize += sizeof(GUID);
  912. (*pGuidCnt)++;
  913. }
  914. if (FLAG_ON(((POBJECTS_AND_NAME_W) pTrustee->ptstrName)->ObjectsPresent,
  915. ACE_INHERITED_OBJECT_TYPE_PRESENT))
  916. {
  917. *pSize += sizeof(GUID);
  918. (*pGuidCnt)++;
  919. }
  920. }
  921. break;
  922. default:
  923. return ERROR_NONE_MAPPED;
  924. }
  925. return ERROR_SUCCESS;
  926. }
  927. ////////////////////////////////////////////////////////////////////////////////
  928. // //
  929. // Function: MartaGetSidFromName //
  930. // //
  931. // Description: Resolves a given Name to Sid. //
  932. // //
  933. // Arguments: //
  934. // //
  935. // [IN pName] Name to be resolved //
  936. // [OUT ppSid] To return the Sid for the trustee //
  937. // //
  938. // Returns: ERROR_SUCCESS if Name to Sid resolution passed //
  939. // Appropriate failure otherwise //
  940. // //
  941. ////////////////////////////////////////////////////////////////////////////////
  942. DWORD
  943. MartaGetSidFromName(
  944. IN LPWSTR pName,
  945. OUT PSID * ppSid
  946. )
  947. {
  948. #define MARTA_DEFAULT_SID_SIZE 64
  949. #define MARTA_DEFAULT_DOMAIN_SIZE 256
  950. WCHAR DomainBuffer[MARTA_DEFAULT_DOMAIN_SIZE];
  951. ULONG SidSize = MARTA_DEFAULT_SID_SIZE;
  952. ULONG DomainSize = MARTA_DEFAULT_DOMAIN_SIZE;
  953. LPWSTR Domain = (LPWSTR) DomainBuffer;
  954. SID_NAME_USE SidNameUse = SidTypeUnknown;
  955. DWORD dwErr = ERROR_SUCCESS;
  956. if (NULL == ppSid)
  957. {
  958. return ERROR_INVALID_PARAMETER;
  959. }
  960. if(0 == _wcsicmp(pName, L"CURRENT_USER"))
  961. {
  962. HANDLE TokenHandle;
  963. dwErr = GetCurrentToken(&TokenHandle);
  964. if(dwErr != ERROR_SUCCESS)
  965. {
  966. return dwErr;
  967. }
  968. dwErr = AccGetSidFromToken(
  969. NULL,
  970. TokenHandle,
  971. TokenUser,
  972. ppSid
  973. );
  974. CloseHandle(TokenHandle);
  975. return dwErr;
  976. }
  977. *ppSid = (PSID) AccAlloc(SidSize);
  978. if(NULL == *ppSid)
  979. {
  980. return ERROR_NOT_ENOUGH_MEMORY;
  981. }
  982. if(!LookupAccountName(
  983. NULL,
  984. pName,
  985. *ppSid,
  986. &SidSize,
  987. Domain,
  988. &DomainSize,
  989. &SidNameUse))
  990. {
  991. dwErr = GetLastError();
  992. if(dwErr == ERROR_INSUFFICIENT_BUFFER)
  993. {
  994. dwErr = ERROR_SUCCESS;
  995. if (SidSize > MARTA_DEFAULT_SID_SIZE)
  996. {
  997. AccFree(*ppSid);
  998. *ppSid = (PSID) AccAlloc(SidSize);
  999. if (*ppSid == NULL)
  1000. {
  1001. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1002. goto End;
  1003. }
  1004. }
  1005. if(DomainSize > MARTA_DEFAULT_DOMAIN_SIZE)
  1006. {
  1007. Domain = (LPWSTR) AccAlloc(DomainSize * sizeof(WCHAR));
  1008. if (NULL == Domain)
  1009. {
  1010. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1011. goto End;
  1012. }
  1013. }
  1014. if(!LookupAccountName(
  1015. NULL,
  1016. pName,
  1017. *ppSid,
  1018. &SidSize,
  1019. Domain,
  1020. &DomainSize,
  1021. &SidNameUse))
  1022. {
  1023. dwErr = GetLastError();
  1024. goto End;
  1025. }
  1026. }
  1027. }
  1028. End:
  1029. if (Domain != (LPWSTR) DomainBuffer)
  1030. {
  1031. AccFree(Domain);
  1032. }
  1033. if (ERROR_SUCCESS != dwErr)
  1034. {
  1035. if (NULL != *ppSid)
  1036. {
  1037. AccFree(*ppSid);
  1038. *ppSid = NULL;
  1039. }
  1040. }
  1041. return dwErr;
  1042. }
  1043. ////////////////////////////////////////////////////////////////////////////////
  1044. // //
  1045. // Function: MartaGetGuid //
  1046. // //
  1047. // Description: Resolves a given Guid Name to a Guid struct. //
  1048. // //
  1049. // Arguments: //
  1050. // //
  1051. // [IN pObjectName] Name to be resolved //
  1052. // [IN ObjectType] Object type of the name to be resolved //
  1053. // [OUT pGuid] To return the guid //
  1054. // //
  1055. // Returns: ERROR_SUCCESS if Name to guid resolution passed //
  1056. // Appropriate failure otherwise //
  1057. // //
  1058. ////////////////////////////////////////////////////////////////////////////////
  1059. DWORD
  1060. MartaGetGuid(
  1061. IN LPWSTR pObjectName,
  1062. IN SE_OBJECT_TYPE ObjectType,
  1063. OUT GUID * pGuid
  1064. )
  1065. {
  1066. switch (ObjectType)
  1067. {
  1068. case SE_DS_OBJECT:
  1069. case SE_DS_OBJECT_ALL:
  1070. break;
  1071. default:
  1072. return ERROR_INVALID_PARAMETER;
  1073. }
  1074. return MartaConvertNameToGuid[ObjectType](
  1075. pObjectName,
  1076. pGuid
  1077. );
  1078. }
  1079. ////////////////////////////////////////////////////////////////////////////////
  1080. // //
  1081. // Function: AccRewriteSetEntriesInAcl //
  1082. // //
  1083. // Description: Resolves a given Name to Sid. //
  1084. // //
  1085. // Arguments: //
  1086. // //
  1087. // [IN cCountOfExplicitEntries] Number of items in list //
  1088. // [IN pListOfExplicitEntries] List of entries to be added //
  1089. // [IN OldAcl] The old acl to add the entries to //
  1090. // [OUT pNewAcl] To return the new acl //
  1091. // //
  1092. // Returns: ERROR_SUCCESS if everything passed //
  1093. // Appropriate failure otherwise //
  1094. // //
  1095. ////////////////////////////////////////////////////////////////////////////////
  1096. DWORD
  1097. WINAPI
  1098. AccRewriteSetEntriesInAcl(
  1099. IN ULONG cCountOfExplicitEntries,
  1100. IN PEXPLICIT_ACCESS_W pListOfExplicitEntries,
  1101. IN PACL OldAcl,
  1102. OUT PACL * pNewAcl
  1103. )
  1104. {
  1105. PMARTA_ACCESS_INFO pAccessInfo = NULL;
  1106. PACCESS_MASK pAceMaskInfo = NULL;
  1107. PACE_HEADER pAce = NULL;
  1108. GUID * pGuid = NULL;
  1109. GUID * pCurrentGuid = NULL;
  1110. POBJECTS_AND_NAME_W pObjName = NULL;
  1111. PUCHAR pAcl = NULL;
  1112. USHORT OldAceCnt = 0;
  1113. USHORT NewAceCnt = 0;
  1114. ULONG ExplicitAceCnt = 0;
  1115. ULONG NewAclSize = sizeof(ACL);
  1116. BOOL bCanonical = TRUE;
  1117. DWORD dwErr = ERROR_SUCCESS;
  1118. ULONG i = 0;
  1119. ULONG j = 0;
  1120. ULONG GuidCnt = 0;
  1121. ULONG ObjectsPresent = 0;
  1122. UCHAR AclRevision = ACL_REVISION;
  1123. if ((NULL == pNewAcl) || ((NULL != OldAcl) && (!RtlValidAcl(OldAcl))))
  1124. {
  1125. return ERROR_INVALID_PARAMETER;
  1126. }
  1127. *pNewAcl = NULL;
  1128. //
  1129. // If the number of entries to be added is zero then make a copy of the Old
  1130. // Acl as it is. Do not try to convert it into Canonical form if it's not.
  1131. //
  1132. if (0 == cCountOfExplicitEntries)
  1133. {
  1134. if (NULL != OldAcl)
  1135. {
  1136. *pNewAcl = (PACL) AccAlloc(OldAcl->AclSize);
  1137. if (NULL == *pNewAcl)
  1138. {
  1139. return ERROR_NOT_ENOUGH_MEMORY;
  1140. }
  1141. memcpy((PUCHAR) *pNewAcl, (PUCHAR) OldAcl, OldAcl->AclSize);
  1142. }
  1143. return ERROR_SUCCESS;
  1144. }
  1145. //
  1146. // Canonical acls processing will be done as in the past.
  1147. // Note: We now support non-canonical acls as well..
  1148. //
  1149. bCanonical = MartaIsExplicitAclCanonical(OldAcl, &ExplicitAceCnt);
  1150. //
  1151. // The Mask for all the aces is stored in a pAceMaskInfo and modified as
  1152. // dictated by the ExplicitAccess entries.
  1153. //
  1154. if (NULL != OldAcl)
  1155. {
  1156. OldAceCnt = OldAcl->AceCount;
  1157. NewAclSize = OldAcl->AclSize;
  1158. NewAceCnt = OldAceCnt;
  1159. pAceMaskInfo = (PACCESS_MASK) AccAlloc(sizeof(ACCESS_MASK) * OldAceCnt);
  1160. if (NULL == pAceMaskInfo)
  1161. {
  1162. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1163. goto End;
  1164. }
  1165. AclRevision = OldAcl->AclRevision;
  1166. }
  1167. //
  1168. // Note: cCountOfExplicitEntries is non-zero at this point.
  1169. //
  1170. pAccessInfo = (PMARTA_ACCESS_INFO) AccAlloc(sizeof(MARTA_ACCESS_INFO) * cCountOfExplicitEntries);
  1171. if (NULL == pAccessInfo)
  1172. {
  1173. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1174. goto End;
  1175. }
  1176. //
  1177. // Initialize the temp structures for the acl and the explicit entries.
  1178. //
  1179. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1180. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1181. {
  1182. pAceMaskInfo[j] = ((PKNOWN_ACE) pAce)->Mask;
  1183. }
  1184. for (i = 0; i < cCountOfExplicitEntries; i++)
  1185. {
  1186. pAccessInfo[i].pServerSid = NULL;
  1187. pAccessInfo[i].pSid = NULL;
  1188. pAccessInfo[i].pObjectTypeGuid = NULL;
  1189. pAccessInfo[i].pInheritedObjectTypeGuid = NULL;
  1190. pAccessInfo[i].Mask = pListOfExplicitEntries[i].grfAccessPermissions;
  1191. }
  1192. //
  1193. // Compute the size required to add this explicit entry to the acl.
  1194. //
  1195. for (i = 0; i < cCountOfExplicitEntries; i++)
  1196. {
  1197. dwErr = MartaGetExplicitAccessEntrySize(
  1198. pListOfExplicitEntries + i,
  1199. pAccessInfo + i,
  1200. &GuidCnt,
  1201. &AclRevision
  1202. );
  1203. CONDITIONAL_EXIT(dwErr, End);
  1204. }
  1205. //
  1206. // For TRUSTEE_IS_OBJECTS_AND_NAME, resolve the GuidNames to Guids and store
  1207. // them in the temp structure.
  1208. //
  1209. if (0 != GuidCnt)
  1210. {
  1211. pGuid = pCurrentGuid = (GUID *) AccAlloc(sizeof(GUID) * GuidCnt);
  1212. if (NULL == pGuid)
  1213. {
  1214. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1215. goto End;
  1216. }
  1217. for (i = 0; i < cCountOfExplicitEntries; i++)
  1218. {
  1219. pObjName = (POBJECTS_AND_NAME_W) pListOfExplicitEntries[i].Trustee.ptstrName;
  1220. ObjectsPresent = pObjName->ObjectsPresent;
  1221. if (FLAG_ON(ObjectsPresent, ACE_OBJECT_TYPE_PRESENT))
  1222. {
  1223. dwErr = MartaGetGuid(
  1224. pObjName->ObjectTypeName,
  1225. pObjName->ObjectType,
  1226. pCurrentGuid
  1227. );
  1228. CONDITIONAL_EXIT(dwErr, End);
  1229. pAccessInfo[i].pObjectTypeGuid = pCurrentGuid++;
  1230. }
  1231. if (FLAG_ON(ObjectsPresent, ACE_INHERITED_OBJECT_TYPE_PRESENT))
  1232. {
  1233. dwErr = MartaGetGuid(
  1234. pObjName->InheritedObjectTypeName,
  1235. pObjName->ObjectType,
  1236. pCurrentGuid
  1237. );
  1238. CONDITIONAL_EXIT(dwErr, End);
  1239. pAccessInfo[i].pInheritedObjectTypeGuid = pCurrentGuid++;
  1240. }
  1241. }
  1242. }
  1243. //
  1244. // Compute the effect of explict entries added on the exisiting acl.
  1245. // The size of an explicit entry will be set to zero if the entry will be
  1246. // absorbed by some existing ace.
  1247. // The Mask for an ace will be set to zero if the AceMask flags have been
  1248. // nulled out by explicit entries.
  1249. //
  1250. for (i = 0; i < cCountOfExplicitEntries; i++)
  1251. {
  1252. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1253. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1254. {
  1255. //
  1256. // Skip Inherited aces.
  1257. //
  1258. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1259. {
  1260. continue;
  1261. }
  1262. dwErr = MartaCompareAcesAndMarkMasks(
  1263. (PUCHAR) pAce,
  1264. pAceMaskInfo + j,
  1265. pListOfExplicitEntries + i,
  1266. pAccessInfo + i,
  1267. bCanonical
  1268. );
  1269. CONDITIONAL_EXIT(dwErr, End);
  1270. }
  1271. }
  1272. //
  1273. // Compute the size required for the new acl and the number of aces in it.
  1274. //
  1275. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1276. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1277. {
  1278. if (0 == pAceMaskInfo[j])
  1279. {
  1280. NewAclSize -= pAce->AceSize;
  1281. NewAceCnt--;
  1282. }
  1283. }
  1284. for (i = 0; i < cCountOfExplicitEntries; i++)
  1285. {
  1286. if (0 != pAccessInfo[i].Size)
  1287. {
  1288. NewAclSize += pAccessInfo[i].Size;
  1289. NewAceCnt++;
  1290. }
  1291. }
  1292. *pNewAcl = (PACL) AccAlloc(NewAclSize);
  1293. if (NULL == *pNewAcl)
  1294. {
  1295. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1296. goto End;
  1297. }
  1298. if (FALSE == InitializeAcl(*pNewAcl, NewAclSize, AclRevision))
  1299. {
  1300. dwErr = GetLastError();
  1301. goto End;
  1302. }
  1303. (*pNewAcl)->AceCount = NewAceCnt;
  1304. pAcl = ((PUCHAR) *pNewAcl) + sizeof(ACL);
  1305. for (i = 0; i < cCountOfExplicitEntries; i++)
  1306. {
  1307. //
  1308. // Add all the DENY ACES to the ACL.
  1309. //
  1310. switch (pListOfExplicitEntries[i].grfAccessMode)
  1311. {
  1312. case DENY_ACCESS:
  1313. case SET_AUDIT_SUCCESS:
  1314. case SET_AUDIT_FAILURE:
  1315. dwErr = MartaAddExplicitEntryToAcl(
  1316. &pAcl,
  1317. pListOfExplicitEntries + i,
  1318. pAccessInfo + i
  1319. );
  1320. CONDITIONAL_EXIT(dwErr, End);
  1321. break;
  1322. default:
  1323. break;
  1324. }
  1325. }
  1326. //
  1327. // Copy the explicit aces from the OldAcl that have not been invalidated by
  1328. // the new Aces added.
  1329. // Inherited aces will be copied afterthe explict ones have been copied.
  1330. //
  1331. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1332. for (j = 0; j < ExplicitAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1333. {
  1334. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1335. {
  1336. continue;
  1337. }
  1338. if (0 != pAceMaskInfo[j])
  1339. {
  1340. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1341. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1342. pAcl += pAce->AceSize;
  1343. }
  1344. }
  1345. //
  1346. // Add all the NON-DENY ACES to the ACL.
  1347. // DENY aces have already been added.
  1348. //
  1349. // If the ACL was canonical then follow the old behavior i.e. add the
  1350. // remaining explicit entries to the beginning of the "allowed" acl.
  1351. // Otherwise, add the ACEs to the end of the explicit part of the ACL.
  1352. //
  1353. if (FALSE == bCanonical)
  1354. {
  1355. for (; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1356. {
  1357. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1358. {
  1359. continue;
  1360. }
  1361. if (0 != pAceMaskInfo[j])
  1362. {
  1363. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1364. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1365. pAcl += pAce->AceSize;
  1366. }
  1367. }
  1368. for (i = 0; i < cCountOfExplicitEntries; i++)
  1369. {
  1370. switch (pListOfExplicitEntries[i].grfAccessMode)
  1371. {
  1372. case GRANT_ACCESS:
  1373. case SET_ACCESS:
  1374. dwErr = MartaAddExplicitEntryToAcl(
  1375. &pAcl,
  1376. pListOfExplicitEntries + i,
  1377. pAccessInfo + i
  1378. );
  1379. CONDITIONAL_EXIT(dwErr, End);
  1380. break;
  1381. default:
  1382. break;
  1383. }
  1384. }
  1385. }
  1386. else
  1387. {
  1388. for (i = 0; i < cCountOfExplicitEntries; i++)
  1389. {
  1390. switch (pListOfExplicitEntries[i].grfAccessMode)
  1391. {
  1392. case GRANT_ACCESS:
  1393. case SET_ACCESS:
  1394. dwErr = MartaAddExplicitEntryToAcl(
  1395. &pAcl,
  1396. pListOfExplicitEntries + i,
  1397. pAccessInfo + i
  1398. );
  1399. CONDITIONAL_EXIT(dwErr, End);
  1400. break;
  1401. default:
  1402. break;
  1403. }
  1404. }
  1405. for (; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1406. {
  1407. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1408. {
  1409. continue;
  1410. }
  1411. if (0 != pAceMaskInfo[j])
  1412. {
  1413. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1414. ((PKNOWN_ACE) pAcl)->Mask = pAceMaskInfo[j];
  1415. pAcl += pAce->AceSize;
  1416. }
  1417. }
  1418. }
  1419. //
  1420. // Add the inherited aces to the new ACL. This will reorder the ACEs so that
  1421. // the EXPLICIT ACEs precede the INHERITED ONES but will not arrange the ACL
  1422. // in canonical form if it was not to start with.
  1423. //
  1424. pAce = (PACE_HEADER) FirstAce(OldAcl);
  1425. for (j = 0; j < OldAceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  1426. {
  1427. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  1428. {
  1429. memcpy((PUCHAR) pAcl, (PUCHAR) pAce, pAce->AceSize);
  1430. pAcl += pAce->AceSize;
  1431. }
  1432. }
  1433. End:
  1434. if (NULL != pAccessInfo)
  1435. {
  1436. for (i = 0; i < cCountOfExplicitEntries; i++ )
  1437. {
  1438. if (NULL != pAccessInfo[i].pServerSid)
  1439. {
  1440. AccFree(pAccessInfo[i].pServerSid);
  1441. }
  1442. if (NULL != pAccessInfo[i].pSid)
  1443. {
  1444. AccFree(pAccessInfo[i].pSid);
  1445. }
  1446. }
  1447. AccFree(pAccessInfo);
  1448. }
  1449. if (NULL != pGuid)
  1450. {
  1451. AccFree(pGuid);
  1452. }
  1453. if (NULL != pAceMaskInfo)
  1454. {
  1455. AccFree(pAceMaskInfo);
  1456. }
  1457. if (ERROR_SUCCESS != dwErr)
  1458. {
  1459. if (NULL != *pNewAcl)
  1460. {
  1461. AccFree(*pNewAcl);
  1462. *pNewAcl = NULL;
  1463. }
  1464. }
  1465. return dwErr;
  1466. }