CommonSecurityDescriptorTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. // CommonSecurityDescriptorTest.cs - NUnit Test Cases for CommonSecurityDescriptor
  2. //
  3. // Authors:
  4. // James Bellinger <[email protected]>
  5. //
  6. // Copyright (C) 2012 James Bellinger
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Security.AccessControl;
  10. using System.Security.Principal;
  11. using NUnit.Framework;
  12. namespace MonoTests.System.Security.AccessControl
  13. {
  14. [TestFixture]
  15. public class CommonSecurityDescriptorTest
  16. {
  17. [Test]
  18. public void DefaultOwnerAndGroup ()
  19. {
  20. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  21. (false, false, ControlFlags.None, null, null, null, null);
  22. Assert.IsNull (csd.Owner);
  23. Assert.IsNull (csd.Group);
  24. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  25. | ControlFlags.SelfRelative, csd.ControlFlags);
  26. }
  27. [Test]
  28. public void GetBinaryForm ()
  29. {
  30. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  31. (false, false, ControlFlags.None, null, null, null, null);
  32. Assert.AreEqual (20, csd.BinaryLength);
  33. byte[] binaryForm = new byte[csd.BinaryLength];
  34. csd.GetBinaryForm (binaryForm, 0);
  35. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative,
  36. csd.ControlFlags);
  37. // The default 'Allow Everyone Full Access' serializes as NOT having a
  38. // DiscretionaryAcl, as the above demonstrates (byte 3 is 0 not 4).
  39. Assert.AreEqual (new byte[20] {
  40. 1, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  41. }, binaryForm);
  42. // Changing SystemAcl protection does nothing special.
  43. csd.SetSystemAclProtection (true, true);
  44. Assert.AreEqual (20, csd.BinaryLength);
  45. // Modifying the DiscretionaryAcl (even effective no-ops like this) causes serialization.
  46. csd.SetDiscretionaryAclProtection (false, true);
  47. Assert.AreEqual (48, csd.BinaryLength);
  48. }
  49. [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
  50. public void GetBinaryFormOffset ()
  51. {
  52. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  53. (false, false, ControlFlags.None, null, null, null, null);
  54. csd.GetBinaryForm (new byte[csd.BinaryLength], 1);
  55. }
  56. [Test, ExpectedException (typeof (ArgumentNullException))]
  57. public void GetBinaryFormNull ()
  58. {
  59. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  60. (false, false, ControlFlags.None, null, null, null, null);
  61. csd.GetBinaryForm (null, 0);
  62. }
  63. [Test]
  64. public void AefaModifiedFlagIsStoredOnDiscretionaryAcl ()
  65. {
  66. CommonSecurityDescriptor csd1, csd2;
  67. // Incidentally this shows the DiscretionaryAcl is NOT cloned.
  68. csd1 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
  69. csd2 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, csd1.DiscretionaryAcl);
  70. Assert.AreSame (csd1.DiscretionaryAcl, csd2.DiscretionaryAcl);
  71. Assert.AreEqual ("", csd1.GetSddlForm (AccessControlSections.Access));
  72. csd2.SetDiscretionaryAclProtection (false, true);
  73. Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd1.GetSddlForm (AccessControlSections.Access));
  74. Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd2.GetSddlForm (AccessControlSections.Access));
  75. }
  76. [Test]
  77. public void AefaRoundtrip ()
  78. {
  79. CommonSecurityDescriptor csd;
  80. csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
  81. Assert.AreEqual (20, csd.BinaryLength);
  82. byte[] binaryForm1 = new byte[csd.BinaryLength];
  83. csd.GetBinaryForm (binaryForm1, 0);
  84. csd = new CommonSecurityDescriptor (false, false, new RawSecurityDescriptor (binaryForm1, 0));
  85. byte[] binaryForm2 = new byte[csd.BinaryLength];
  86. csd.GetBinaryForm (binaryForm2, 0);
  87. Assert.AreEqual (binaryForm1, binaryForm2);
  88. }
  89. [Test]
  90. public void GetSddlFormAefaRemovesDacl ()
  91. {
  92. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  93. (false, false, ControlFlags.None, null, null, null, null);
  94. Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
  95. Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
  96. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  97. | ControlFlags.SelfRelative,
  98. csd.ControlFlags);
  99. Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
  100. Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
  101. Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
  102. csd.SetDiscretionaryAclProtection (false, true);
  103. Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
  104. Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
  105. Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
  106. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  107. | ControlFlags.SelfRelative,
  108. csd.ControlFlags);
  109. csd.SetDiscretionaryAclProtection (true, true);
  110. Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
  111. Assert.AreEqual ("D:P(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
  112. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  113. | ControlFlags.DiscretionaryAclProtected
  114. | ControlFlags.SelfRelative,
  115. csd.ControlFlags);
  116. csd.SetDiscretionaryAclProtection (false, false);
  117. Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
  118. Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
  119. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  120. | ControlFlags.SelfRelative,
  121. csd.ControlFlags);
  122. }
  123. [Test, ExpectedException (typeof (ArgumentException))]
  124. public void ContainerAndDSConsistencyEnforcedA ()
  125. {
  126. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  127. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  128. DiscretionaryAcl dacl = new DiscretionaryAcl (true, true, 0);
  129. new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, dacl);
  130. }
  131. [Test, ExpectedException (typeof (ArgumentException))]
  132. public void ContainerAndDSConsistencyEnforcedB ()
  133. {
  134. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  135. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  136. SystemAcl sacl = new SystemAcl (false, false, 0);
  137. new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, sacl, null);
  138. }
  139. [Test, ExpectedException (typeof (ArgumentException))]
  140. public void ContainerAndDSConsistencyEnforcedInSetter ()
  141. {
  142. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  143. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  144. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  145. (true, false, ControlFlags.None, userSid, groupSid, null, null);
  146. csd.DiscretionaryAcl = new DiscretionaryAcl (true, true, 0);
  147. }
  148. [Test]
  149. public void DefaultDaclIsAllowEveryoneFullAccess ()
  150. {
  151. SecurityIdentifier userSid = new SecurityIdentifier ("SY");
  152. SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
  153. SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD");
  154. CommonSecurityDescriptor csd; DiscretionaryAcl dacl; CommonAce ace;
  155. csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, userSid, groupSid, null, null);
  156. dacl = csd.DiscretionaryAcl;
  157. Assert.AreEqual (1, dacl.Count);
  158. ace = (CommonAce)dacl [0];
  159. Assert.AreEqual (-1, ace.AccessMask);
  160. Assert.AreEqual (AceFlags.None, ace.AceFlags);
  161. Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
  162. Assert.AreEqual (20, ace.BinaryLength);
  163. Assert.IsFalse (ace.IsCallback);
  164. Assert.IsFalse (ace.IsInherited);
  165. Assert.AreEqual (0, ace.OpaqueLength);
  166. Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
  167. csd = new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, null);
  168. dacl = csd.DiscretionaryAcl;
  169. Assert.AreEqual (1, dacl.Count);
  170. ace = (CommonAce)dacl [0];
  171. Assert.AreEqual (-1, ace.AccessMask);
  172. Assert.AreEqual (AceFlags.ObjectInherit | AceFlags.ContainerInherit, ace.AceFlags);
  173. Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
  174. Assert.AreEqual (20, ace.BinaryLength);
  175. Assert.IsFalse (ace.IsCallback);
  176. Assert.IsFalse (ace.IsInherited);
  177. Assert.AreEqual (0, ace.OpaqueLength);
  178. Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
  179. }
  180. [Test]
  181. public void PurgeDefaultDacl ()
  182. {
  183. SecurityIdentifier userSid = new SecurityIdentifier ("SY");
  184. SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
  185. SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD");
  186. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  187. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  188. DiscretionaryAcl dacl = csd.DiscretionaryAcl;
  189. Assert.AreEqual (1, dacl.Count);
  190. csd.PurgeAccessControl (userSid);
  191. Assert.AreEqual (1, dacl.Count);
  192. csd.PurgeAccessControl (everyoneSid);
  193. Assert.AreEqual (0, dacl.Count);
  194. }
  195. [Test]
  196. public void PurgeNullSaclWithoutError ()
  197. {
  198. SecurityIdentifier userSid = new SecurityIdentifier ("SY");
  199. SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
  200. CommonSecurityDescriptor csd = new CommonSecurityDescriptor
  201. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  202. csd.PurgeAudit (userSid);
  203. Assert.IsNull (csd.SystemAcl);
  204. }
  205. [Test]
  206. public void OwnerAndGroupAreReferences ()
  207. {
  208. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  209. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  210. CommonSecurityDescriptor csd;
  211. csd = new CommonSecurityDescriptor
  212. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  213. Assert.AreSame (groupSid, csd.Group);
  214. Assert.AreSame (userSid, csd.Owner);
  215. }
  216. [Test]
  217. public void ProtectionChangesFlags ()
  218. {
  219. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  220. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  221. CommonSecurityDescriptor csd;
  222. csd = new CommonSecurityDescriptor
  223. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  224. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  225. | ControlFlags.SelfRelative, csd.ControlFlags);
  226. csd.SetDiscretionaryAclProtection (true, false);
  227. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  228. | ControlFlags.DiscretionaryAclProtected
  229. | ControlFlags.SelfRelative, csd.ControlFlags);
  230. csd.SetSystemAclProtection (true, false); // despite not being *present*
  231. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  232. | ControlFlags.DiscretionaryAclProtected
  233. | ControlFlags.SystemAclProtected
  234. | ControlFlags.SelfRelative, csd.ControlFlags);
  235. }
  236. [Test]
  237. public void ProtectionPreserveInheritanceIgnoredUnlessProtectedTrue ()
  238. {
  239. CommonSecurityDescriptor descriptor;
  240. descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
  241. Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
  242. descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
  243. descriptor.SetDiscretionaryAclProtection (true, false);
  244. Assert.AreEqual (1, descriptor.DiscretionaryAcl.Count);
  245. descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
  246. descriptor.SetDiscretionaryAclProtection (false, false);
  247. Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
  248. descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
  249. descriptor.SetDiscretionaryAclProtection (true, true);
  250. Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
  251. descriptor.SetDiscretionaryAclProtection (false, false);
  252. Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
  253. descriptor.SetDiscretionaryAclProtection (false, true);
  254. Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
  255. descriptor.SetDiscretionaryAclProtection (true, false);
  256. Assert.AreEqual (1, descriptor.DiscretionaryAcl.Count);
  257. }
  258. static CommonSecurityDescriptor ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor()
  259. {
  260. SecurityIdentifier sid = new SecurityIdentifier ("WD");
  261. RawAcl acl = new RawAcl (GenericAcl.AclRevision, 1);
  262. acl.InsertAce (0, new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null));
  263. acl.InsertAce (1, new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid, false, null));
  264. CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
  265. (false, false, ControlFlags.None, null, null, null, null);
  266. descriptor.DiscretionaryAcl = new DiscretionaryAcl (false, false, acl);
  267. return descriptor;
  268. }
  269. [Test]
  270. public void DaclPresent ()
  271. {
  272. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  273. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  274. CommonSecurityDescriptor csd;
  275. csd = new CommonSecurityDescriptor
  276. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  277. Assert.IsNotNull (csd.DiscretionaryAcl);
  278. Assert.IsTrue (csd.IsDiscretionaryAclCanonical);
  279. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
  280. Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
  281. csd = new CommonSecurityDescriptor
  282. (false, false, ControlFlags.DiscretionaryAclPresent, userSid, groupSid, null, null);
  283. Assert.IsNotNull (csd.DiscretionaryAcl);
  284. Assert.IsTrue (csd.IsDiscretionaryAclCanonical);
  285. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
  286. DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
  287. csd = new CommonSecurityDescriptor
  288. (false, false, ControlFlags.None, userSid, groupSid, null, dacl);
  289. Assert.AreSame (dacl, csd.DiscretionaryAcl);
  290. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
  291. csd = new CommonSecurityDescriptor
  292. (false, false, ControlFlags.DiscretionaryAclPresent, userSid, groupSid, null, dacl);
  293. Assert.AreSame (dacl, csd.DiscretionaryAcl);
  294. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
  295. }
  296. [Test]
  297. public void SaclPresent ()
  298. {
  299. SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
  300. SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
  301. SystemAcl sacl = new SystemAcl (false, false, 0);
  302. CommonSecurityDescriptor csd;
  303. csd = new CommonSecurityDescriptor
  304. (false, false, ControlFlags.None, userSid, groupSid, null, null);
  305. Assert.IsNull (csd.SystemAcl);
  306. Assert.IsTrue (csd.IsSystemAclCanonical);
  307. csd = new CommonSecurityDescriptor
  308. (false, false, ControlFlags.SystemAclPresent, userSid, groupSid, null, null);
  309. Assert.IsNull (csd.SystemAcl);
  310. Assert.IsTrue (csd.IsSystemAclCanonical);
  311. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
  312. csd = new CommonSecurityDescriptor
  313. (false, false, ControlFlags.None, userSid, groupSid, sacl, null);
  314. Assert.AreSame (sacl, csd.SystemAcl);
  315. Assert.IsTrue (csd.IsSystemAclCanonical);
  316. Assert.AreEqual (0, csd.SystemAcl.Count);
  317. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  318. | ControlFlags.SystemAclPresent
  319. | ControlFlags.SelfRelative, csd.ControlFlags);
  320. csd.SystemAcl = null;
  321. Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
  322. | ControlFlags.SelfRelative, csd.ControlFlags);
  323. }
  324. }
  325. }