// ObjectSecurityTest.cs - NUnit Test Cases for ObjectSecurity // // Authors: // James Bellinger // // 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 ObjectSecurityTest { [Test] public void Defaults () { TestSecurity security = new TestSecurity (); Assert.IsTrue (security.AreAccessRulesCanonical); Assert.IsTrue (security.AreAuditRulesCanonical); Assert.IsFalse (security.AreAccessRulesProtected); Assert.IsFalse (security.AreAuditRulesProtected); Assert.IsNull (security.GetGroup (typeof (SecurityIdentifier))); Assert.IsNull (security.GetOwner (typeof (SecurityIdentifier))); } [Test] public void DefaultsForSddlAndBinary () { TestSecurity security = new TestSecurity (); Assert.AreEqual ("D:", security.GetSecurityDescriptorSddlForm (AccessControlSections.All)); Assert.AreEqual (28, security.GetSecurityDescriptorBinaryForm ().Length); } [Test] public void SetSddlForm () { TestSecurity security = new TestSecurity (); SecurityIdentifier groupSid = new SecurityIdentifier ("WD"); SecurityIdentifier userSid = new SecurityIdentifier ("SY"); security.SetGroup (groupSid); security.SetOwner (userSid); Assert.AreEqual ("G:WD", security.GetSecurityDescriptorSddlForm (AccessControlSections.Group)); Assert.AreEqual ("O:SY", security.GetSecurityDescriptorSddlForm (AccessControlSections.Owner)); security.SetSecurityDescriptorSddlForm ("O:BG", AccessControlSections.Owner); Assert.AreEqual ("O:BG", security.GetSecurityDescriptorSddlForm (AccessControlSections.Owner)); Assert.AreEqual (new SecurityIdentifier ("BG"), security.GetOwner (typeof (SecurityIdentifier))); } [Test] public void SetSddlFormAllowsFlags () { TestSecurity security = new TestSecurity (); security.SetSecurityDescriptorSddlForm ("G:BA", AccessControlSections.Group | AccessControlSections.Owner); Assert.AreEqual ("", security.GetSecurityDescriptorSddlForm (AccessControlSections.Owner)); Assert.AreEqual ("G:BA", security.GetSecurityDescriptorSddlForm (AccessControlSections.Group)); } [Test, ExpectedException (typeof (ArgumentNullException))] public void SetGroupThrowsOnNull () { TestSecurity security = new TestSecurity (); security.SetGroup (null); } [Test, ExpectedException (typeof (ArgumentNullException))] public void SetOwnerThrowsOnNull () { TestSecurity security = new TestSecurity (); security.SetOwner (null); } [Test, ExpectedException (typeof (ArgumentNullException))] public void PurgeThrowsOnNull () { TestSecurity security = new TestSecurity (); security.PurgeAccessRules (null); } [Test] public void AllTypesAcceptedOnGetGroupOwnerUntilTheyAreSet () { TestSecurity security = new TestSecurity (); Assert.IsNull (security.GetGroup (typeof (void))); Assert.IsNull (security.GetOwner (typeof (int))); SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD"); security.SetOwner (everyoneSid); bool throwsOnInt = false; try { security.GetOwner (typeof (int)); } catch (ArgumentException) { throwsOnInt = true; } Assert.IsTrue (throwsOnInt); bool throwsOnSuperclass = false; try { security.GetOwner (typeof (IdentityReference)); } catch (ArgumentException) { throwsOnSuperclass = true; } Assert.IsTrue (throwsOnSuperclass); Assert.IsNull (security.GetGroup (typeof (void))); Assert.IsInstanceOfType (typeof (SecurityIdentifier), security.GetOwner (typeof (SecurityIdentifier))); } [Test] public void ModifyAccessRuleAllowsDerivedTypeAndCallsModifyAccessButNothingChanges () { bool modifiedRet, modifiedOut; SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD"); TestSecurity security = new TestSecurity (); DerivedAccessRule rule = new DerivedAccessRule (everyoneSid, TestRights.One, AccessControlType.Allow); modifiedRet = security.ModifyAccessRule (AccessControlModification.Add, rule, out modifiedOut); Assert.AreEqual (modifiedRet, modifiedOut); Assert.IsTrue (modifiedRet); Assert.IsTrue (security.modify_access_called); Assert.AreEqual ("D:", security.GetSecurityDescriptorSddlForm (AccessControlSections.All)); // (1) There is no external abstract/virtual 'get collection', // (2) The overrides in this test call this base class, which does not change it, and // (3) There are methods based on the collection value such as GetSecurityDescriptorSddlForm. // Conclusion: Collection is internal and manipulated by derived classes. } [Test, ExpectedException (typeof (ArgumentException))] public void ModifyAccessRuleThrowsOnWrongType () { bool modified; SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD"); TestSecurity security = new TestSecurity (); FileSystemAccessRule rule = new FileSystemAccessRule (everyoneSid, FileSystemRights.FullControl, AccessControlType.Allow); security.ModifyAccessRule (AccessControlModification.Add, rule, out modified); } [Test] public void Reset () { bool modifiedRet, modifiedOut; SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD"); TestSecurity security = new TestSecurity (); TestAccessRule rule = new TestAccessRule (everyoneSid, TestRights.One, AccessControlType.Allow); modifiedRet = security.ModifyAccessRule (AccessControlModification.Reset, rule, out modifiedOut); } [Test] public void Protection () { TestSecurity security = new TestSecurity (); security.SetAccessRuleProtection (true, true); Assert.IsTrue (security.AreAccessRulesProtected); Assert.IsFalse (security.AreAuditRulesProtected); security.SetAuditRuleProtection (true, false); Assert.IsTrue (security.AreAccessRulesProtected); Assert.IsTrue (security.AreAuditRulesProtected); security.SetAccessRuleProtection (false, false); Assert.IsFalse (security.AreAccessRulesProtected); Assert.IsTrue (security.AreAuditRulesProtected); security.SetAuditRuleProtection (false, true); Assert.IsFalse (security.AreAccessRulesProtected); Assert.IsFalse (security.AreAuditRulesProtected); } enum TestRights { One = 1 } class DerivedAccessRule : TestAccessRule { public DerivedAccessRule (IdentityReference identity, TestRights rights, AccessControlType type) : base (identity, rights, type) { } } class TestAccessRule : AccessRule { public TestAccessRule (IdentityReference identity, TestRights rights, AccessControlType type) : this (identity, rights, false, InheritanceFlags.None, PropagationFlags.None, type) { } public TestAccessRule (IdentityReference identity, TestRights rights, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) : base (identity, (int)rights, isInherited, inheritanceFlags, propagationFlags, type) { } } class TestAuditRule : AuditRule { public TestAuditRule (IdentityReference identity, TestRights rights, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) : base (identity, (int)rights, isInherited, inheritanceFlags, propagationFlags, flags) { } } class TestSecurity : ObjectSecurity { internal bool modify_access_called; public TestSecurity () : base (false, false) { } public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) { return new TestAccessRule (identityReference, (TestRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type); } public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) { return new TestAuditRule (identityReference, (TestRights)accessMask, isInherited, inheritanceFlags, propagationFlags, flags); } protected override bool ModifyAccess (AccessControlModification modification, AccessRule rule, out bool modified) { modify_access_called = true; modified = true; return modified; } protected override bool ModifyAudit (AccessControlModification modification, AuditRule rule, out bool modified) { modified = false; return modified; } public override Type AccessRightType { get { return typeof (TestRights); } } public override Type AccessRuleType { get { return typeof (TestAccessRule); } } public override Type AuditRuleType { get { return typeof (TestAuditRule); } } } } }