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.

502 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: ace.cpp
  8. //
  9. // This file contains the implementation of the CAce class
  10. //
  11. //--------------------------------------------------------------------------
  12. #include "aclpriv.h"
  13. #include "sddl.h" // ConvertSidToStringSid
  14. CAce::CAce(PACE_HEADER pAce):pszInheritSourceName(NULL),
  15. iInheritSourceLevel(0)
  16. {
  17. ULONG nSidLength = 0;
  18. ULONG nAceLength = SIZEOF(KNOWN_ACE) - SIZEOF(ULONG);
  19. ZeroMemory(this, SIZEOF(CAce));
  20. sidType = SidTypeInvalid;
  21. InheritedObjectType = GUID_NULL;
  22. if (pAce != NULL)
  23. {
  24. PSID psidT;
  25. // Copy the header and mask
  26. *(PACE_HEADER)this = *pAce;
  27. Mask = ((PKNOWN_ACE)pAce)->Mask;
  28. // Is this an object ACE?
  29. if (IsObjectAceType(pAce))
  30. {
  31. GUID *pGuid;
  32. nAceLength = SIZEOF(KNOWN_OBJECT_ACE) - SIZEOF(ULONG);
  33. // Copy the object type guid if present
  34. pGuid = RtlObjectAceObjectType(pAce);
  35. if (pGuid)
  36. {
  37. Flags |= ACE_OBJECT_TYPE_PRESENT;
  38. ObjectType = *pGuid;
  39. nAceLength += SIZEOF(GUID);
  40. }
  41. //
  42. //ACE_INHERITED_OBJECT_TYPE_PRESENT is invalid without
  43. //either of container inherit or object inherit flags.
  44. //NTRAID#NTBUG9-287737-2001/01/23-hiteshr
  45. //
  46. if (pAce->AceFlags & ACE_INHERIT_ALL)
  47. {
  48. //Copy the inherit type guid if present
  49. pGuid = RtlObjectAceInheritedObjectType(pAce);
  50. if (pGuid)
  51. {
  52. Flags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
  53. InheritedObjectType = *pGuid;
  54. nAceLength += SIZEOF(GUID);
  55. }
  56. }
  57. }
  58. // Copy the SID
  59. psidT = GetAceSid(pAce);
  60. nSidLength = GetLengthSid(psidT);
  61. psid = (PSID)LocalAlloc(LPTR, nSidLength);
  62. if (psid)
  63. CopyMemory(psid, psidT, nSidLength);
  64. }
  65. AceSize = (USHORT)(nAceLength + nSidLength);
  66. }
  67. CAce::~CAce()
  68. {
  69. if (psid != NULL)
  70. LocalFree(psid);
  71. LocalFreeString(&pszName);
  72. LocalFreeString(&pszType);
  73. LocalFreeString(&pszAccessType);
  74. LocalFreeString(&pszInheritType);
  75. LocalFreeString(&pszInheritSourceName);
  76. }
  77. void
  78. CAce::SetInheritSourceInfo(LPCTSTR psz, INT level)
  79. {
  80. #define MAX_BUFFER 1000
  81. iInheritSourceLevel = level;
  82. if(psz != NULL)
  83. {
  84. SetString(&pszInheritSourceName,psz);
  85. }
  86. else
  87. {
  88. WCHAR Buffer[MAX_BUFFER];
  89. if(IsInheritedAce())
  90. {
  91. LoadString(::hModule, IDS_FROM_PARENT, Buffer, ARRAYSIZE(Buffer));
  92. SetString(&pszInheritSourceName,Buffer);
  93. iInheritSourceLevel = -1;
  94. }
  95. else
  96. {
  97. LoadString(::hModule, IDS_NOT_INHERITED, Buffer, ARRAYSIZE(Buffer));
  98. SetString(&pszInheritSourceName,Buffer);
  99. iInheritSourceLevel = 0;
  100. }
  101. }
  102. }
  103. LPTSTR
  104. CAce::LookupName(LPCTSTR pszServer, LPSECURITYINFO2 psi2)
  105. {
  106. if (SidTypeInvalid == sidType)
  107. {
  108. PUSER_LIST pUserList = NULL;
  109. LPCTSTR pszN = NULL;
  110. LPCTSTR pszL = NULL;
  111. sidType = SidTypeUnknown;
  112. if (LookupSid(psid, pszServer, psi2, &pUserList))
  113. {
  114. sidType = pUserList->rgUsers[0].SidType;
  115. pszN = pUserList->rgUsers[0].pszName;
  116. pszL = pUserList->rgUsers[0].pszLogonName;
  117. }
  118. SetName(pszN, pszL);
  119. if (pUserList)
  120. LocalFree(pUserList);
  121. }
  122. return pszName;
  123. }
  124. void
  125. CAce::SetName(LPCTSTR pszN, LPCTSTR pszL)
  126. {
  127. LocalFreeString(&pszName);
  128. if (!BuildUserDisplayName(&pszName, pszN, pszL) && psid)
  129. ConvertSidToStringSid(psid, &pszName);
  130. }
  131. void
  132. CAce::SetSid(PSID p, LPCTSTR pszName, LPCTSTR pszLogonName, SID_NAME_USE type)
  133. {
  134. ULONG nSidLength = 0;
  135. ULONG nAceLength = SIZEOF(KNOWN_ACE) - SIZEOF(ULONG);
  136. if (psid != NULL)
  137. {
  138. LocalFree(psid);
  139. psid = NULL;
  140. }
  141. if (p != NULL)
  142. {
  143. nSidLength = GetLengthSid(p);
  144. psid = (PSID)LocalAlloc(LPTR, nSidLength);
  145. if (psid)
  146. CopyMemory(psid, p, nSidLength);
  147. }
  148. if (Flags != 0)
  149. {
  150. nAceLength = SIZEOF(KNOWN_OBJECT_ACE) - SIZEOF(ULONG);
  151. if (Flags & ACE_OBJECT_TYPE_PRESENT)
  152. nAceLength += SIZEOF(GUID);
  153. if (Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  154. nAceLength += SIZEOF(GUID);
  155. }
  156. AceSize = (USHORT)(nAceLength + nSidLength);
  157. sidType = type;
  158. SetName(pszName, pszLogonName);
  159. }
  160. void
  161. CAce::SetString(LPTSTR *ppszDest, LPCTSTR pszSrc)
  162. {
  163. LocalFreeString(ppszDest);
  164. if (NULL != pszSrc)
  165. LocalAllocString(ppszDest, pszSrc);
  166. }
  167. PACE_HEADER
  168. CAce::Copy() const
  169. {
  170. PACE_HEADER pAceCopy = (PACE_HEADER)LocalAlloc(LPTR, AceSize);
  171. CopyTo(pAceCopy);
  172. return pAceCopy;
  173. }
  174. void
  175. CAce::CopyTo(PACE_HEADER pAceDest) const
  176. {
  177. if (pAceDest)
  178. {
  179. ULONG nAceLength = SIZEOF(KNOWN_ACE) - SIZEOF(ULONG);
  180. ULONG nSidLength;
  181. // Copy the header and mask
  182. *pAceDest = *(PACE_HEADER)this;
  183. ((PKNOWN_ACE)pAceDest)->Mask = Mask;
  184. // Is this an object ACE?
  185. if (IsObjectAceType(this))
  186. {
  187. GUID *pGuid;
  188. nAceLength = SIZEOF(KNOWN_OBJECT_ACE) - SIZEOF(ULONG);
  189. // Copy the object flags
  190. ((PKNOWN_OBJECT_ACE)pAceDest)->Flags = Flags;
  191. // Copy the object type guid if present
  192. pGuid = RtlObjectAceObjectType(pAceDest);
  193. if (pGuid)
  194. {
  195. *pGuid = ObjectType;
  196. nAceLength += SIZEOF(GUID);
  197. }
  198. // Copy the inherit type guid if present
  199. pGuid = RtlObjectAceInheritedObjectType(pAceDest);
  200. if (pGuid)
  201. {
  202. *pGuid = InheritedObjectType;
  203. nAceLength += SIZEOF(GUID);
  204. }
  205. }
  206. // Copy the SID
  207. nSidLength = GetLengthSid(psid);
  208. CopyMemory(GetAceSid(pAceDest), psid, nSidLength);
  209. // The size should already be correct, but set it here to be sure.
  210. pAceDest->AceSize = (USHORT)(nAceLength + nSidLength);
  211. }
  212. }
  213. int
  214. CAce::CompareType(const CAce *pAceCompare) const
  215. {
  216. //
  217. // Determine which ACE preceeds the other in canonical ordering.
  218. //
  219. // Return negative if this ACE preceeds pAceCompare, positive if
  220. // pAceCompare preceeds this ACE, and 0 if they are equivalent in
  221. // canonical ordering.
  222. //
  223. BOOL b1;
  224. BOOL b2;
  225. //
  226. // First check inheritance. Inherited ACEs follow non-inherited ACEs.
  227. //
  228. b1 = AceFlags & INHERITED_ACE;
  229. b2 = pAceCompare->AceFlags & INHERITED_ACE;
  230. if (b1 != b2)
  231. {
  232. // One (and only one) of the ACEs is inherited.
  233. return (b1 ? 1 : -1);
  234. }
  235. //
  236. // Next, Allow ACEs follow Deny ACEs.
  237. // Note that allow/deny has no effect on the ordering of Audit ACEs.
  238. //
  239. b1 = (AceType == ACCESS_ALLOWED_ACE_TYPE ||
  240. AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE);
  241. b2 = (pAceCompare->AceType == ACCESS_ALLOWED_ACE_TYPE ||
  242. pAceCompare->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE);
  243. if (b1 != b2)
  244. {
  245. // One of the ACEs is an Allow ACE.
  246. return (b1 ? 1 : -1);
  247. }
  248. //
  249. // Next, Object ACEs follow non-object ACEs.
  250. //
  251. b1 = (AceType >= ACCESS_MIN_MS_OBJECT_ACE_TYPE &&
  252. AceType <= ACCESS_MAX_MS_OBJECT_ACE_TYPE);
  253. b2 = (pAceCompare->AceType >= ACCESS_MIN_MS_OBJECT_ACE_TYPE &&
  254. pAceCompare->AceType <= ACCESS_MAX_MS_OBJECT_ACE_TYPE);
  255. if (b1 != b2)
  256. {
  257. // One of the ACEs is an Object ACE.
  258. return (b1 ? 1 : -1);
  259. }
  260. return 0;
  261. }
  262. DWORD
  263. CAce::Merge(const CAce *pAce2)
  264. {
  265. DWORD dwStatus;
  266. DWORD dwMergeFlags = 0;
  267. DWORD dwResult;
  268. if (pAce2 == NULL)
  269. return MERGE_FAIL;
  270. //if either of the ace is inherited and they are not from the same parent
  271. if( GetInheritSourceLevel() != pAce2->GetInheritSourceLevel() )
  272. return MERGE_FAIL;
  273. //
  274. // The ACEs have to be the same basic type and have the same SID or
  275. // there's no hope.
  276. //
  277. if (!IsEqualACEType(AceType, pAce2->AceType) ||
  278. !EqualSid(psid, pAce2->psid))
  279. return MERGE_FAIL;
  280. if (!IsEqualGUID(InheritedObjectType, pAce2->InheritedObjectType))
  281. return MERGE_FAIL; // incompatible inherit object types
  282. if (Flags & ACE_OBJECT_TYPE_PRESENT)
  283. dwMergeFlags |= MF_OBJECT_TYPE_1_PRESENT;
  284. if (pAce2->Flags & ACE_OBJECT_TYPE_PRESENT)
  285. dwMergeFlags |= MF_OBJECT_TYPE_2_PRESENT;
  286. if (IsEqualGUID(ObjectType, pAce2->ObjectType))
  287. dwMergeFlags |= MF_OBJECT_TYPE_EQUAL;
  288. if (IsAuditAlarmACE(AceType))
  289. dwMergeFlags |= MF_AUDIT_ACE_TYPE;
  290. dwStatus = MergeAceHelper(AceFlags,
  291. Mask,
  292. pAce2->AceFlags,
  293. pAce2->Mask,
  294. dwMergeFlags,
  295. &dwResult);
  296. switch (dwStatus)
  297. {
  298. case MERGE_MODIFIED_FLAGS:
  299. AceFlags = (UCHAR)dwResult;
  300. break;
  301. case MERGE_MODIFIED_MASK:
  302. Mask = dwResult;
  303. break;
  304. }
  305. return dwStatus;
  306. }
  307. BOOL
  308. IsEqualACEType(DWORD dwType1, DWORD dwType2)
  309. {
  310. if (dwType1 >= ACCESS_MIN_MS_OBJECT_ACE_TYPE &&
  311. dwType1 <= ACCESS_MAX_MS_OBJECT_ACE_TYPE)
  312. dwType1 -= (ACCESS_ALLOWED_OBJECT_ACE_TYPE - ACCESS_ALLOWED_ACE_TYPE);
  313. if (dwType2 >= ACCESS_MIN_MS_OBJECT_ACE_TYPE &&
  314. dwType2 <= ACCESS_MAX_MS_OBJECT_ACE_TYPE)
  315. dwType2 -= (ACCESS_ALLOWED_OBJECT_ACE_TYPE - ACCESS_ALLOWED_ACE_TYPE);
  316. return (dwType1 == dwType2);
  317. }
  318. DWORD
  319. MergeAceHelper(DWORD dwAceFlags1,
  320. DWORD dwMask1,
  321. DWORD dwAceFlags2,
  322. DWORD dwMask2,
  323. DWORD dwMergeFlags,
  324. LPDWORD pdwResult)
  325. {
  326. // Assumptions:
  327. // The ACEs are the same basic type.
  328. // The SIDs are the same for both.
  329. // The Inherit object type is the same for both.
  330. if (pdwResult == NULL)
  331. return MERGE_FAIL;
  332. *pdwResult = 0;
  333. if (dwMergeFlags & MF_OBJECT_TYPE_EQUAL)
  334. {
  335. if (dwAceFlags1 == dwAceFlags2)
  336. {
  337. //
  338. // Everything matches except maybe the mask, which
  339. // can be combined here.
  340. //
  341. if (AllFlagsOn(dwMask1, dwMask2))
  342. return MERGE_OK_1;
  343. else if (AllFlagsOn(dwMask2, dwMask1))
  344. return MERGE_OK_2;
  345. *pdwResult = dwMask1 | dwMask2;
  346. return MERGE_MODIFIED_MASK;
  347. }
  348. else if ((dwAceFlags1 & VALID_INHERIT_FLAGS) == (dwAceFlags2 & VALID_INHERIT_FLAGS) &&
  349. dwMask1 == dwMask2)
  350. {
  351. // If 2 audit aces are identical except for the audit
  352. // type (success/fail), the flags can be combined.
  353. if (dwMergeFlags & MF_AUDIT_ACE_TYPE)
  354. {
  355. *pdwResult = dwAceFlags1 | dwAceFlags2;
  356. return MERGE_MODIFIED_FLAGS;
  357. }
  358. }
  359. else if ((dwAceFlags1 & (NO_PROPAGATE_INHERIT_ACE | INHERITED_ACE | FAILED_ACCESS_ACE_FLAG | SUCCESSFUL_ACCESS_ACE_FLAG))
  360. == (dwAceFlags2 & (NO_PROPAGATE_INHERIT_ACE | INHERITED_ACE | FAILED_ACCESS_ACE_FLAG | SUCCESSFUL_ACCESS_ACE_FLAG)))
  361. {
  362. // The NO_PROPAGATE_INHERIT_ACE bit is the same for both
  363. if (dwMask1 == dwMask2)
  364. {
  365. // The masks are the same, so we can combine inherit flags
  366. *pdwResult = dwAceFlags1;
  367. // INHERIT_ONLY_ACE should be turned on only if it is
  368. // already on in both ACEs, otherwise leave it off.
  369. if (!(dwAceFlags2 & INHERIT_ONLY_ACE))
  370. *pdwResult &= ~INHERIT_ONLY_ACE;
  371. // Combine the remaining inherit flags and return
  372. *pdwResult |= dwAceFlags2 & (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE);
  373. return MERGE_MODIFIED_FLAGS;
  374. }
  375. else if (AllFlagsOn(dwMask1, dwMask2))
  376. {
  377. // mask1 contains mask2. If Ace1 is inherited onto all of the
  378. // same things that Ace2 is, then Ace2 is redundant.
  379. if ((!(dwAceFlags1 & INHERIT_ONLY_ACE) || (dwAceFlags2 & INHERIT_ONLY_ACE))
  380. && AllFlagsOn(dwAceFlags1 & ACE_INHERIT_ALL, dwAceFlags2 & ACE_INHERIT_ALL))
  381. return MERGE_OK_1;
  382. }
  383. else if (AllFlagsOn(dwMask2, dwMask1))
  384. {
  385. // Same as above, reversed.
  386. if ((!(dwAceFlags2 & INHERIT_ONLY_ACE) || (dwAceFlags1 & INHERIT_ONLY_ACE))
  387. && AllFlagsOn(dwAceFlags2 & ACE_INHERIT_ALL, dwAceFlags1 & ACE_INHERIT_ALL))
  388. return MERGE_OK_2;
  389. }
  390. }
  391. }
  392. else if (dwAceFlags1 == dwAceFlags2)
  393. {
  394. if (!(dwMergeFlags & MF_OBJECT_TYPE_1_PRESENT) &&
  395. AllFlagsOn(dwMask1, dwMask2))
  396. {
  397. //
  398. // The other ACE has a non-NULL object type but this ACE has no object
  399. // type and a mask that includes all of the bits in the other one.
  400. // I.e. This ACE implies the other ACE.
  401. //
  402. return MERGE_OK_1;
  403. }
  404. else if (!(dwMergeFlags & MF_OBJECT_TYPE_2_PRESENT) &&
  405. AllFlagsOn(dwMask2, dwMask1))
  406. {
  407. //
  408. // This ACE has a non-NULL object type but the other ACE has no object
  409. // type and a mask that includes all of the bits in this one.
  410. // I.e. The other ACE implies this ACE.
  411. //
  412. return MERGE_OK_2;
  413. }
  414. }
  415. return MERGE_FAIL;
  416. }