|
|
@@ -0,0 +1,249 @@
|
|
|
+// DiscretionaryAclTest.cs - NUnit Test Cases for DiscretionaryAcl
|
|
|
+//
|
|
|
+// Authors:
|
|
|
+// James Bellinger <[email protected]>
|
|
|
+//
|
|
|
+// Copyright (C) 2012 James Bellinger
|
|
|
+
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Security.AccessControl;
|
|
|
+using System.Security.Principal;
|
|
|
+using NUnit.Framework;
|
|
|
+
|
|
|
+namespace MonoTests.System.Security.AccessControl
|
|
|
+{
|
|
|
+ [TestFixture]
|
|
|
+ public class DiscretionaryAclTest
|
|
|
+ {
|
|
|
+ [Test]
|
|
|
+ public void StartsEmpty ()
|
|
|
+ {
|
|
|
+ Assert.AreEqual (0, new DiscretionaryAcl (false, false, 0).Count);
|
|
|
+ Assert.AreEqual (0, new DiscretionaryAcl (false, false, null).Count);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void AddAccessCommonAce ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+
|
|
|
+ CommonAce ace = (CommonAce)dacl[0];
|
|
|
+ Assert.AreEqual (1, ace.AccessMask);
|
|
|
+ Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
|
|
|
+ Assert.IsFalse (ace.IsInherited);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void AddAccessCommonAceUsingDSOverload ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid ());
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+
|
|
|
+ CommonAce ace = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (1, ace.AccessMask);
|
|
|
+ Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
|
|
|
+ Assert.IsFalse (ace.IsInherited);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test, ExpectedException (typeof (InvalidOperationException))]
|
|
|
+ public void AddAccessObjectAceNonDSFailsEvenIfObjectAceFlagsNoneImplyingCommonAce ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.None, Guid.Empty, Guid.Empty);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test, ExpectedException (typeof (InvalidOperationException))]
|
|
|
+ public void AddAccessFailsOnNonCanonical ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BU");
|
|
|
+
|
|
|
+ RawAcl acl = new RawAcl (RawAcl.AclRevision, 0);
|
|
|
+ acl.InsertAce (0, new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null));
|
|
|
+ acl.InsertAce (1, new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null));
|
|
|
+
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
|
|
|
+ Assert.IsFalse (dacl.IsCanonical);
|
|
|
+ Assert.AreEqual (2, dacl.Count);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test, ExpectedException (typeof (ArgumentException))]
|
|
|
+ public void InheritanceFlagsRequireContainer ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BU");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 3, InheritanceFlags.ContainerInherit, PropagationFlags.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test, ExpectedException (typeof (ArgumentException))]
|
|
|
+ public void PropagationFlagsRequireInheritanceFlagsForAdd ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BU");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0);
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.InheritOnly);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void AddAccessObjectAceAndCommonAce ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.Empty);
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.None, Guid.Empty, Guid.Empty);
|
|
|
+ Assert.AreEqual (2, dacl.Count);
|
|
|
+
|
|
|
+ CommonAce cace = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (1, cace.AccessMask);
|
|
|
+ Assert.AreEqual ("S-1-5-32-544", cace.SecurityIdentifier.Value);
|
|
|
+ Assert.IsFalse (cace.IsCallback);
|
|
|
+ Assert.IsFalse (cace.IsInherited);
|
|
|
+
|
|
|
+ ObjectAce oace = (ObjectAce)dacl [1];
|
|
|
+ Assert.AreEqual (1, oace.AccessMask);
|
|
|
+ Assert.AreEqual ("S-1-5-32-544", oace.SecurityIdentifier.Value);
|
|
|
+ Assert.IsFalse (oace.IsCallback);
|
|
|
+ Assert.IsFalse (oace.IsInherited);
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 2, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.None, Guid.Empty, Guid.Empty);
|
|
|
+ Assert.AreEqual (2, dacl.Count);
|
|
|
+
|
|
|
+ CommonAce cace2 = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (3, cace2.AccessMask);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
|
|
|
+ public void InvalidAccessControlType ()
|
|
|
+ {
|
|
|
+ // This is also testing the fact that the AccessControlType is checked before the
|
|
|
+ // InheritanceFlags are validated -- IsContainer is false here, so if the InheritanceFlags
|
|
|
+ // were checked first, ArgumentException would be thrown instead.
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+ dacl.AddAccess ((AccessControlType)43210, sid, 1, InheritanceFlags.ContainerInherit, PropagationFlags.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void RemoveSpecific ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+
|
|
|
+ RemoveSpecificBegin (sid, dacl, InheritanceFlags.None);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (0, dacl.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void RemoveSpecificUsingDSOverload ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
|
|
|
+
|
|
|
+ RemoveSpecificBegin (sid, dacl, InheritanceFlags.None);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None,
|
|
|
+ ObjectAceFlags.None, Guid.Empty, Guid.Empty);
|
|
|
+ Assert.AreEqual (0, dacl.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void RemoveSpecificIsContainer ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0);
|
|
|
+
|
|
|
+ RemoveSpecificBegin (sid, dacl, InheritanceFlags.ObjectInherit);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.ObjectInherit, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (0, dacl.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void RemoveSpecificIgnoresPropagationFlagsWhenMatchingInheritanceFlagsNone()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BA");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+
|
|
|
+ RemoveSpecificBegin (sid, dacl, InheritanceFlags.None);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3,
|
|
|
+ InheritanceFlags.None, PropagationFlags.InheritOnly);
|
|
|
+ Assert.AreEqual (0, dacl.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ void RemoveSpecificBegin (SecurityIdentifier sid, DiscretionaryAcl dacl, InheritanceFlags inheritanceFlags)
|
|
|
+ {
|
|
|
+ SecurityIdentifier otherSid = new SecurityIdentifier ("BU");
|
|
|
+
|
|
|
+ dacl.AddAccess (AccessControlType.Allow, sid, 3, inheritanceFlags, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Deny, sid, 1, inheritanceFlags, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, otherSid, 1, inheritanceFlags, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 1, inheritanceFlags, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ Assert.AreEqual (3, ((CommonAce)dacl [0]).AccessMask);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3,
|
|
|
+ inheritanceFlags ^ InheritanceFlags.ContainerInherit,
|
|
|
+ PropagationFlags.None);
|
|
|
+ Assert.AreEqual (1, dacl.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void PropagationFlagsDoNotRequireInheritanceFlagsForRemoveSpecific ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier sid = new SecurityIdentifier ("BU");
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
|
|
|
+ dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3,
|
|
|
+ InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Test]
|
|
|
+ public void SetAccess ()
|
|
|
+ {
|
|
|
+ SecurityIdentifier adminSid = new SecurityIdentifier ("BA"); // S-1-5-32-544
|
|
|
+ SecurityIdentifier userSid = new SecurityIdentifier ("BU"); // S-1-5-32-545
|
|
|
+
|
|
|
+ DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0);
|
|
|
+ dacl.SetAccess (AccessControlType.Allow, adminSid, 1, InheritanceFlags.ObjectInherit, PropagationFlags.None);
|
|
|
+ dacl.SetAccess (AccessControlType.Allow, userSid, 2, InheritanceFlags.None, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (2, dacl.Count);
|
|
|
+
|
|
|
+ CommonAce ace = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (adminSid, ace.SecurityIdentifier);
|
|
|
+ Assert.AreEqual (1, ace.AccessMask);
|
|
|
+
|
|
|
+ dacl.SetAccess (AccessControlType.Allow, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
|
|
|
+ Assert.AreNotEqual (4, ace.AccessMask); // remove and add, not modify, despite AccessMask having a setter
|
|
|
+ ace = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (4, ace.AccessMask);
|
|
|
+
|
|
|
+ dacl.SetAccess (AccessControlType.Deny, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
|
|
|
+ Assert.AreEqual (3, dacl.Count);
|
|
|
+ ace = (CommonAce)dacl [0];
|
|
|
+ Assert.AreEqual (AceQualifier.AccessDenied, ace.AceQualifier);
|
|
|
+ ace = (CommonAce)dacl [1];
|
|
|
+ Assert.AreEqual (AceQualifier.AccessAllowed, ace.AceQualifier);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|