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.

430 lines
14 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // //
  3. // Microsoft Windows //
  4. // Copyright (C) Microsoft Corporation, 1999. //
  5. // //
  6. // File: geefa.cxx //
  7. // //
  8. // Contents: New marta rewrite functions for GetExplicitEntriesFromAcl //
  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 <aclapi.h>
  28. #include <global.h>
  29. }
  30. #define MARTA_ALIGNED_SID_LENGTH(p) ((PtrAlignSize(RtlLengthSid((p)))))
  31. DWORD
  32. MartaGetAceToEntrySize(
  33. IN PACE_HEADER pAce,
  34. OUT PULONG pLen,
  35. OUT PULONG pCount
  36. );
  37. DWORD
  38. MartaFillExplicitEntries(
  39. IN PACL pacl,
  40. IN PUCHAR Buffer,
  41. IN ULONG AccessCnt
  42. );
  43. DWORD
  44. AccRewriteGetExplicitEntriesFromAcl(
  45. IN PACL pacl,
  46. OUT PULONG pcCountOfExplicitEntries,
  47. OUT PEXPLICIT_ACCESS_W * pListOfExplicitEntries
  48. );
  49. ////////////////////////////////////////////////////////////////////////////////
  50. // //
  51. // Function: AccRewriteGetExplicitEntriesFromAcl //
  52. // //
  53. // Description: Extract the explicit entries from an acl. //
  54. // //
  55. // Arguments: //
  56. // //
  57. // [IN pacl] Acl to be converted //
  58. // [OUT pcCountOfExplicitEntries] To return the number of entries found //
  59. // [OUT pListOfExplicitEntries] To return the list of entries found //
  60. // //
  61. // Returns: ERROR_SUCCESS if the Acl could be converted to expcilt entries //
  62. // Appropriate failure otherwise //
  63. // //
  64. ////////////////////////////////////////////////////////////////////////////////
  65. DWORD
  66. AccRewriteGetExplicitEntriesFromAcl(
  67. IN PACL pacl,
  68. OUT PULONG pcCountOfExplicitEntries,
  69. OUT PEXPLICIT_ACCESS_W * pListOfExplicitEntries)
  70. {
  71. DWORD dwErr = ERROR_SUCCESS;
  72. ULONG AccessCnt = 0;
  73. ULONG Size = 0;
  74. USHORT AceCnt = 0;
  75. ULONG Count = 0;
  76. ULONG j = 0;
  77. ULONG Len = 0;
  78. PUCHAR Buffer = NULL;
  79. PACE_HEADER pAce = NULL;
  80. if ((NULL == pcCountOfExplicitEntries) || (NULL == pListOfExplicitEntries))
  81. {
  82. return ERROR_INVALID_PARAMETER;
  83. }
  84. *pcCountOfExplicitEntries = 0;
  85. *pListOfExplicitEntries = NULL;
  86. if ((NULL == pacl) || (0 == pacl->AceCount))
  87. {
  88. return ERROR_SUCCESS;
  89. }
  90. if (!RtlValidAcl(pacl))
  91. {
  92. return ERROR_INVALID_PARAMETER;
  93. }
  94. AceCnt = pacl->AceCount;
  95. pAce = (PACE_HEADER) FirstAce(pacl);
  96. for (j = 0; j < AceCnt; j++, pAce = (PACE_HEADER) NextAce(pAce))
  97. {
  98. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  99. {
  100. continue;
  101. }
  102. dwErr = MartaGetAceToEntrySize(pAce, &Len, &Count);
  103. CONDITIONAL_EXIT(dwErr, End);
  104. AccessCnt += Count;
  105. Size += Count * (Len + sizeof(EXPLICIT_ACCESS_W));
  106. }
  107. if (0 == Size)
  108. {
  109. goto End;
  110. }
  111. Buffer = (PUCHAR) AccAlloc(Size);
  112. if (NULL == Buffer)
  113. {
  114. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  115. goto End;
  116. }
  117. dwErr = MartaFillExplicitEntries(pacl, Buffer, AccessCnt);
  118. if (ERROR_SUCCESS != dwErr)
  119. {
  120. goto End;
  121. }
  122. *pcCountOfExplicitEntries = AccessCnt;
  123. *pListOfExplicitEntries = (PEXPLICIT_ACCESS_W) Buffer;
  124. End:
  125. if (ERROR_SUCCESS != dwErr)
  126. {
  127. if (NULL != Buffer)
  128. {
  129. AccFree(Buffer);
  130. }
  131. }
  132. return dwErr;
  133. }
  134. ////////////////////////////////////////////////////////////////////////////////
  135. // //
  136. // Function: MartaGetAceToEntrySize //
  137. // //
  138. // Description: Compute: //
  139. // Size needed to convert a given ace into explicit entry //
  140. // Number of explicit entries for this ace //
  141. // //
  142. // Arguments: //
  143. // //
  144. // [IN pAce] Ace to be converted to an explicit entry //
  145. // [OUT pLen] To return the length of the entry //
  146. // [OUT pCount] To return the number of explict entries for this ace //
  147. // //
  148. // Returns: ERROR_SUCCESS if the ace could be converted to an expcilt entry //
  149. // Appropriate failure otherwise //
  150. // //
  151. ////////////////////////////////////////////////////////////////////////////////
  152. DWORD
  153. MartaGetAceToEntrySize(
  154. IN PACE_HEADER pAce,
  155. OUT PULONG pLen,
  156. OUT PULONG pCount
  157. )
  158. {
  159. switch (pAce->AceType)
  160. {
  161. case ACCESS_ALLOWED_ACE_TYPE:
  162. case ACCESS_DENIED_ACE_TYPE:
  163. case SYSTEM_AUDIT_ACE_TYPE:
  164. case SYSTEM_ALARM_ACE_TYPE:
  165. *pLen = MARTA_ALIGNED_SID_LENGTH((PSID) &((PKNOWN_ACE) pAce)->SidStart);
  166. break;
  167. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  168. *pLen = MARTA_ALIGNED_SID_LENGTH(RtlCompoundAceServerSid(pAce));
  169. *pLen += sizeof(TRUSTEE_W) + MARTA_ALIGNED_SID_LENGTH(RtlCompoundAceClientSid(pAce));
  170. break;
  171. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  172. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  173. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  174. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  175. *pLen = MARTA_ALIGNED_SID_LENGTH(RtlObjectAceSid(pAce)) + sizeof(OBJECTS_AND_SID);
  176. break;
  177. default:
  178. return ERROR_INVALID_PARAMETER;
  179. }
  180. switch (pAce->AceType)
  181. {
  182. case SYSTEM_AUDIT_ACE_TYPE:
  183. case SYSTEM_ALARM_ACE_TYPE:
  184. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  185. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  186. *pCount = 0;
  187. if (FLAG_ON(pAce->AceFlags, SUCCESSFUL_ACCESS_ACE_FLAG))
  188. {
  189. *pCount += 1;
  190. }
  191. if (FLAG_ON(pAce->AceFlags, FAILED_ACCESS_ACE_FLAG))
  192. {
  193. *pCount += 1;
  194. }
  195. if (0 == *pCount)
  196. {
  197. return ERROR_INVALID_PARAMETER;
  198. }
  199. break;
  200. default:
  201. *pCount = 1;
  202. break;
  203. }
  204. return ERROR_SUCCESS;
  205. }
  206. ////////////////////////////////////////////////////////////////////////////////
  207. // //
  208. // Function: MartaFillExplicitEntries //
  209. // //
  210. // Description: Convert an ace into explicit entry stucture(s) //
  211. // //
  212. // Arguments: //
  213. // //
  214. // [IN pacl] Acl to be converted //
  215. // [IN Buffer] Buffer to be filled with explicit entries //
  216. // [IN AccessCnt] Number of explicitentries created //
  217. // //
  218. // Returns: ERROR_SUCCESS if the acl could be converted to expcilt entries //
  219. // Appropriate failure otherwise //
  220. // //
  221. // Note: Since Audit aces might be converted into one/two entries we need a //
  222. // flag to maintain whethe the given ace was already seen in the last //
  223. // pass. //
  224. // //
  225. ////////////////////////////////////////////////////////////////////////////////
  226. DWORD
  227. MartaFillExplicitEntries(
  228. IN PACL pacl,
  229. IN PUCHAR Buffer,
  230. IN ULONG AccessCnt
  231. )
  232. {
  233. DWORD dwErr = ERROR_SUCCESS;
  234. ULONG AceCnt = pacl->AceCount;
  235. PUCHAR CurrentBuffer = Buffer + sizeof(EXPLICIT_ACCESS_W) * AccessCnt;
  236. ACCESS_MASK Mask = 0;
  237. ULONG j = 0;
  238. ULONG i = 0;
  239. ULONG Length = 0;
  240. PACE_HEADER pAce = NULL;
  241. PSID pSid = NULL;
  242. POBJECTS_AND_SID pObjSid = NULL;
  243. BOOL bFlag = FALSE;
  244. PEXPLICIT_ACCESS_W pExplicit = (PEXPLICIT_ACCESS_W) Buffer;
  245. pAce = (PACE_HEADER) FirstAce(pacl);
  246. for (i = j = 0; i < AceCnt; )
  247. {
  248. if (FLAG_ON(pAce->AceFlags, INHERITED_ACE))
  249. {
  250. i++;
  251. pAce = (PACE_HEADER) NextAce(pAce);
  252. continue;
  253. }
  254. switch (pAce->AceType)
  255. {
  256. case ACCESS_ALLOWED_ACE_TYPE:
  257. case ACCESS_DENIED_ACE_TYPE:
  258. case SYSTEM_AUDIT_ACE_TYPE:
  259. case SYSTEM_ALARM_ACE_TYPE:
  260. Mask = ((PKNOWN_ACE) pAce)->Mask;
  261. pSid = (PSID) &((PKNOWN_ACE) pAce)->SidStart;
  262. Length = MARTA_ALIGNED_SID_LENGTH(pSid);
  263. memcpy(CurrentBuffer, pSid, Length);
  264. BuildTrusteeWithSidW(
  265. &(pExplicit[j].Trustee),
  266. (PSID) CurrentBuffer
  267. );
  268. CurrentBuffer += Length;
  269. break;
  270. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  271. Mask = ((PKNOWN_COMPOUND_ACE) pAce)->Mask;
  272. pSid = (PSID) &((PKNOWN_ACE) pAce)->SidStart;
  273. Length = MARTA_ALIGNED_SID_LENGTH(pSid);
  274. memcpy(CurrentBuffer, pSid, Length);
  275. BuildTrusteeWithSidW(
  276. &(pExplicit[j].Trustee),
  277. (PSID) CurrentBuffer
  278. );
  279. CurrentBuffer += Length;
  280. pSid = (PSID) (((PUCHAR) &(((PKNOWN_ACE) pAce)->SidStart)) + Length);
  281. Length = MARTA_ALIGNED_SID_LENGTH(pSid);
  282. memcpy(CurrentBuffer, pSid, Length);
  283. pSid = (PSID) CurrentBuffer;
  284. CurrentBuffer += Length;
  285. BuildTrusteeWithSidW(
  286. (PTRUSTEE_W) CurrentBuffer,
  287. pSid
  288. );
  289. BuildImpersonateTrusteeW(
  290. &(pExplicit[j].Trustee),
  291. (PTRUSTEE_W) CurrentBuffer
  292. );
  293. CurrentBuffer += sizeof(TRUSTEE_W);
  294. break;
  295. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  296. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  297. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  298. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  299. Mask = ((PKNOWN_OBJECT_ACE) pAce)->Mask;
  300. pSid = RtlObjectAceSid(pAce);
  301. Length = MARTA_ALIGNED_SID_LENGTH(pSid);
  302. memcpy((PUCHAR) CurrentBuffer, (PUCHAR) pSid, Length);
  303. pSid = (PSID) CurrentBuffer;
  304. CurrentBuffer += Length;
  305. pObjSid = (POBJECTS_AND_SID) CurrentBuffer;
  306. CurrentBuffer += sizeof(OBJECTS_AND_SID);
  307. BuildTrusteeWithObjectsAndSidW(
  308. &(pExplicit[j].Trustee),
  309. pObjSid,
  310. RtlObjectAceObjectType(pAce),
  311. RtlObjectAceInheritedObjectType(pAce),
  312. pSid
  313. );
  314. break;
  315. default:
  316. return ERROR_INVALID_PARAMETER;
  317. }
  318. switch (pAce->AceType)
  319. {
  320. case ACCESS_ALLOWED_ACE_TYPE:
  321. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  322. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  323. pExplicit[j].grfAccessMode = GRANT_ACCESS;
  324. break;
  325. case ACCESS_DENIED_ACE_TYPE:
  326. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  327. pExplicit[j].grfAccessMode = DENY_ACCESS;
  328. break;
  329. case SYSTEM_AUDIT_ACE_TYPE:
  330. case SYSTEM_ALARM_ACE_TYPE:
  331. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  332. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  333. if ((FALSE == bFlag) && (FLAG_ON(pAce->AceFlags, SUCCESSFUL_ACCESS_ACE_FLAG)))
  334. {
  335. pExplicit[j].grfAccessMode = SET_AUDIT_SUCCESS;
  336. if (FLAG_ON(pAce->AceFlags, FAILED_ACCESS_ACE_FLAG))
  337. {
  338. bFlag = TRUE;
  339. }
  340. }
  341. else if (FLAG_ON(pAce->AceFlags, FAILED_ACCESS_ACE_FLAG))
  342. {
  343. pExplicit[j].grfAccessMode = SET_AUDIT_FAILURE;
  344. bFlag = FALSE;
  345. }
  346. break;
  347. default:
  348. return ERROR_INVALID_PARAMETER;
  349. }
  350. pExplicit[j].grfAccessPermissions = Mask;
  351. pExplicit[j].grfInheritance = pAce->AceFlags & VALID_INHERIT_FLAGS;
  352. if (FALSE == bFlag)
  353. {
  354. i++;
  355. pAce = (PACE_HEADER) NextAce(pAce);
  356. }
  357. j++;
  358. }
  359. return ERROR_SUCCESS;
  360. }