Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
// AuthorizationRuleTest.cs - NUnit Test Cases for AuthorizationRule
//
// Authors:
// James Bellinger (jfb@zer7.com)
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class AuthorizationRuleTest
{
class TestRule : AuthorizationRule
{
public TestRule (IdentityReference identity,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags)
: base (identity, accessMask, isInherited, inheritanceFlags, propagationFlags)
{
}
}
[Test, ExpectedException (typeof (ArgumentException))]
public void ThrowOnZeroAccessMask ()
{
new TestRule (new SecurityIdentifier (WellKnownSidType.WorldSid, null),
0, false, InheritanceFlags.None, PropagationFlags.None);
}
[Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
public void ThrowOnBadInheritanceFlags ()
{
new TestRule (new SecurityIdentifier (WellKnownSidType.WorldSid, null),
1, false, (InheritanceFlags)(-1), PropagationFlags.None);
}
// While InheritanceFlags.None makes PropagationFlags not *significant*,
// my tests with MS.NET show that it is still *validated*. So, we'll use
// that case with this test to make sure.
[Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
public void ThrowOnBadPropagationFlags ()
{
new TestRule (new SecurityIdentifier (WellKnownSidType.WorldSid, null),
1, false, InheritanceFlags.None, (PropagationFlags)(-1));
}
[Test]
public void AcceptNTAccount ()
{
new TestRule (new NTAccount ("Test"), 1, false, InheritanceFlags.None, PropagationFlags.None);
}
[Test]
public void AcceptSecurityIdentifier ()
{
new TestRule (new SecurityIdentifier (WellKnownSidType.WorldSid, null),
1, false, InheritanceFlags.None, PropagationFlags.None);
}
[Test]
public void AcceptValidFlags ()
{
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
new TestRule (id, 1, false, InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit);
new TestRule (id, 1, false, InheritanceFlags.ObjectInherit, PropagationFlags.InheritOnly);
}
}
}

View File

@@ -0,0 +1,39 @@
//
// CommonAceTest.cs - NUnit Test Cases for CommonAce
//
// Author:
// Kenneth Bell
//
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl {
[TestFixture]
public class CommonAceTest {
[Test]
public void GetBinaryForm ()
{
SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
byte[] buffer = new byte[ace.BinaryLength];
ace.GetBinaryForm (buffer, 0);
byte[] aceBinary = new byte[] {
0x00, 0x00, 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00,
0x20, 0x02, 0x00, 0x00 };
Assert.AreEqual (aceBinary, buffer);
}
[Test]
public void MaxOpaqueLength ()
{
Assert.AreEqual (65459, CommonAce.MaxOpaqueLength (true));
Assert.AreEqual (65459, CommonAce.MaxOpaqueLength (false));
Assert.AreEqual (65423, ObjectAce.MaxOpaqueLength (true));
Assert.AreEqual (65423, ObjectAce.MaxOpaqueLength (false));
}
}
}

View File

@@ -0,0 +1,443 @@
// CommonAclTest.cs - NUnit Test Cases for CommonAcl
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 CommonAclTest
{
[Test]
public void RevisionOK ()
{
DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 0);
Assert.AreEqual (2, dacl.Revision);
}
[Test]
public void RevisionDSOK ()
{
DiscretionaryAcl dacl = new DiscretionaryAcl(false, true, 0);
Assert.AreEqual (4, dacl.Revision);
}
[Test]
public void NullRawAclRevisionOK ()
{
DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, null);
Assert.AreEqual (2, dacl1.Revision);
DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, true, null);
Assert.AreEqual (4, dacl2.Revision);
}
[Test]
public void UsesRawAclRevision ()
{
RawAcl acl1 = new RawAcl (RawAcl.AclRevisionDS, 0);
DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl1);
Assert.AreEqual (4, dacl1.Revision);
RawAcl acl2 = new RawAcl (RawAcl.AclRevision, 0);
DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, true, acl2);
Assert.AreEqual (2, dacl2.Revision);
}
[Test]
public void IndexerMakesCopies ()
{
// This behavior is mentioned in the DiscretionaryAcl RawAcl constructor overload.
// Turns out it applies to more than just the constructor.
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
// RawAcl does not make copies.
RawAcl acl = new RawAcl (RawAcl.AclRevision, 1);
CommonAce ace = new CommonAce (AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, worldSid, false, null);
acl.InsertAce (0, ace);
Assert.AreSame (acl [0], acl [0]);
// CommonAcl does.
SystemAcl sacl = new SystemAcl (false, false, acl);
Assert.AreNotSame (sacl [0], sacl [0]);
// Make sure the copying occurs in the constructor as well as the indexer.
ace.AceFlags = AceFlags.FailedAccess;
Assert.AreEqual (AceFlags.SuccessfulAccess, sacl [0].AceFlags);
}
[Test]
public void EmptyBinaryLengthOK()
{
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
Assert.AreEqual (8, dacl.BinaryLength);
}
[Test]
public void EmptyBinaryFormOK()
{
DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 0);
byte[] buffer = new byte[8];
dacl.GetBinaryForm (buffer, 0);
Assert.AreEqual (2, buffer [0]); // Revision
Assert.AreEqual (8, ToUInt16 (buffer, 2)); // ACL Size
Assert.AreEqual (0, ToUInt16 (buffer, 4)); // ACE Count
}
[Test]
public void EmptyBinaryFormDSOK()
{
DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
byte[] buffer = new byte[8];
dacl.GetBinaryForm (buffer, 0);
Assert.AreEqual (4, buffer [0]); // Revision
Assert.AreEqual (8, ToUInt16 (buffer, 2)); // ACL Size
Assert.AreEqual (0, ToUInt16 (buffer, 4)); // ACE Count
}
[Test] // ... stumbled upon this by choosing Guid.Empty when needing an arbitrary GUID ...
public void GuidEmptyMergesRegardlessOfFlagsAndOpaqueDataIsNotConsidered ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl (new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, true, new byte[12]),
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid, false, new byte[8]), // gets merged
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid,
ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty, false, new byte[8]),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid,
ObjectAceFlags.InheritedObjectAceTypePresent, Guid.Empty, Guid.Empty, true, new byte[16]), // gets merged
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid,
ObjectAceFlags.InheritedObjectAceTypePresent, Guid.Empty, Guid.NewGuid (), true, new byte[4])
});
Assert.AreEqual (236, acl.BinaryLength);
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (3, dacl.Count);
CommonAce cace = (CommonAce)dacl [0];
Assert.AreEqual (12, cace.OpaqueLength);
Assert.AreEqual (5, cace.AccessMask);
Assert.IsTrue (cace.IsCallback);
ObjectAce oace = (ObjectAce)dacl [1];
Assert.AreEqual (8, oace.OpaqueLength);
Assert.AreEqual (3, oace.AccessMask);
Assert.AreEqual (ObjectAceFlags.ObjectAceTypePresent, oace.ObjectAceFlags);
Assert.AreEqual (Guid.Empty, oace.ObjectAceType);
Assert.IsFalse (oace.IsCallback);
}
[Test]
public void DetectsCanonicalMergesAndRemovesInheritedAces ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null)
});
Assert.AreEqual (6, acl.Count);
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (4, dacl.Count);
Assert.AreEqual (AceFlags.None, ((CommonAce)dacl [0]).AceFlags);
Assert.AreEqual (AceFlags.None, ((CommonAce)dacl [1]).AceFlags);
Assert.AreEqual (AceFlags.Inherited, ((CommonAce)dacl [2]).AceFlags);
Assert.AreEqual (AceFlags.Inherited, ((CommonAce)dacl [3]).AceFlags);
Assert.AreEqual (AceQualifier.AccessDenied, ((CommonAce)dacl [0]).AceQualifier);
Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [1]).AceQualifier);
Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [2]).AceQualifier);
Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [3]).AceQualifier);
GenericAce ace7 = dacl[0];
Assert.IsInstanceOfType (typeof (CommonAce), ace7);
dacl.RemoveInheritedAces ();
Assert.AreEqual (2, dacl.Count);
dacl.Purge (sid);
Assert.AreEqual (0, dacl.Count);
}
[Test]
public void MergesAfterSortingForMultipleSids ()
{
SecurityIdentifier adminSid = new SecurityIdentifier
(WellKnownSidType.BuiltinAdministratorsSid, null); // S-1-5-32-544
SecurityIdentifier userSid = new SecurityIdentifier
(WellKnownSidType.BuiltinUsersSid, null); // S-1-5-32-545
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, userSid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 2, adminSid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, userSid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, adminSid, false, null),
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (2, dacl.Count);
CommonAce adminAce = (CommonAce)dacl [0];
Assert.AreEqual (adminSid, adminAce.SecurityIdentifier);
Assert.AreEqual (10, adminAce.AccessMask);
CommonAce userAce = (CommonAce)dacl [1];
Assert.AreEqual (userSid, userAce.SecurityIdentifier);
Assert.AreEqual (5, userAce.AccessMask);
}
[Test]
public void DetectsNonCanonicalAndDoesNotMerge ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsFalse (dacl.IsCanonical);
Assert.AreEqual (4, dacl.Count);
}
[Test]
public void DoesNotMergeOrEvaluateOrderingForInherited ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 1, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 2, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 8, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (4, dacl.Count);
}
[Test]
public void SetterNotSupported ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 2, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (4, dacl.Count);
bool throws1 = false;
try { dacl[0] = acl[0]; } catch (NotSupportedException) { throws1 = true; }
Assert.IsTrue (throws1);
bool throws2 = false;
try { dacl[0] = acl[2]; } catch (NotSupportedException) { throws2 = true; }
Assert.IsTrue (throws2);
}
// FIXME: Uncomment this once CompoundAce is implemented on Mono.
/*
[Test]
public void CompoundAcesAreNotCanonical ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
RawAcl acl = MakeRawAcl(new GenericAce[] {
new CompoundAce (AceFlags.None, 1, CompoundAceType.Impersonation, sid)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsFalse (dacl.IsCanonical);
}
*/
[Test]
public void RemovesMeaninglessAces ()
{
RawAcl acl = GetRemovesMeaninglessAcesAcl ();
DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl1.IsCanonical);
Assert.AreEqual (7, dacl1.Count);
Assert.AreEqual (12, ((KnownAce)dacl1 [0]).AccessMask);
DiscretionaryAcl dacl2 = new DiscretionaryAcl (true, false, acl);
Assert.IsTrue (dacl2.IsCanonical);
Assert.AreEqual (8, dacl2.Count);
Assert.AreEqual (12, ((KnownAce)dacl1 [0]).AccessMask);
}
// shared with BinaryRoundtrip as well
static RawAcl GetRemovesMeaninglessAcesAcl ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
return MakeRawAcl(new GenericAce[] {
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null), // merged
new CommonAce (AceFlags.InheritOnly|AceFlags.ObjectInherit,
AceQualifier.AccessDenied, 42, sid, false, null), // removed ONLY if !IsContainer
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0, sid, false, null), // removed
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null), // merged
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 2, sid, false, null),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 0, sid,
ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid (), false, null), // removed
new ObjectAce (AceFlags.InheritOnly, AceQualifier.AccessAllowed, 1, sid,
ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.NewGuid (), false, null), // removed
new ObjectAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid,
ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid (), false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 0, sid, false, null), // removed
new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 4, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 4, sid, false, null),
new CommonAce (AceFlags.Inherited, AceQualifier.SystemAlarm, 4, sid, false, null), // removed
new CommonAce (AceFlags.Inherited, AceQualifier.SystemAudit, 4, sid, false, null) // removed
});
}
[Test]
public void BinaryRoundtrip ()
{
RawAcl acl = GetRemovesMeaninglessAcesAcl ();
DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl);
byte[] binaryForm1 = new byte[dacl1.BinaryLength];
dacl1.GetBinaryForm (binaryForm1, 0);
DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, false, new RawAcl (binaryForm1, 0));
byte[] binaryForm2 = new byte[dacl2.BinaryLength];
dacl2.GetBinaryForm (binaryForm2, 0);
Assert.AreEqual (binaryForm1.Length, binaryForm2.Length);
for (int i = 0; i < binaryForm1.Length; i ++)
Assert.AreEqual (binaryForm1 [i], binaryForm2 [i]);
}
[Test]
public void ContiguousRangeSorting ()
{
SecurityIdentifier[] sids = new SecurityIdentifier[] {
new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null), // S-1-5-32-544
new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null), // S-1-5-32-545
new SecurityIdentifier (WellKnownSidType.WorldSid, null), // S-1-1-0
new SecurityIdentifier ("S-1-5-40"),
new SecurityIdentifier ("S-1-5-30-123"),
new SecurityIdentifier ("S-1-5-32-99"),
new SecurityIdentifier ("S-1-5-23-45-67"),
new SecurityIdentifier ("S-1-5-32-5432"),
new SecurityIdentifier ("S-1-0-2"),
new SecurityIdentifier ("S-1-6-0")
};
GenericAce[] aces = new GenericAce[sids.Length];
for (int i = 0; i < aces.Length; i ++)
aces [i] = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sids[i], false, null);
RawAcl acl = MakeRawAcl (aces);
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.IsTrue (dacl.IsCanonical);
Assert.AreEqual (sids[8], ((CommonAce)dacl [0]).SecurityIdentifier); // S-1-0-2
Assert.AreEqual (sids[2], ((CommonAce)dacl [1]).SecurityIdentifier); // S-1-1-0
Assert.AreEqual (sids[3], ((CommonAce)dacl [2]).SecurityIdentifier); // S-1-5-40
Assert.AreEqual (sids[4], ((CommonAce)dacl [3]).SecurityIdentifier); // S-1-5-30-123
Assert.AreEqual (sids[5], ((CommonAce)dacl [4]).SecurityIdentifier); // S-1-5-32-99
Assert.AreEqual (sids[0], ((CommonAce)dacl [5]).SecurityIdentifier); // S-1-5-32-544
Assert.AreEqual (sids[1], ((CommonAce)dacl [6]).SecurityIdentifier); // S-1-5-32-545
Assert.AreEqual (sids[7], ((CommonAce)dacl [7]).SecurityIdentifier); // S-1-5-32-5432
Assert.AreEqual (sids[6], ((CommonAce)dacl [8]).SecurityIdentifier); // S-1-5-23-45-67
Assert.AreEqual (sids[9], ((CommonAce)dacl [9]).SecurityIdentifier); // S-1-6-0
}
static RawAcl MakeRawAcl (GenericAce[] aces)
{
RawAcl acl = new RawAcl (RawAcl.AclRevision, 0);
for (int i = 0; i < aces.Length; i ++) { acl.InsertAce (i, aces [i]); }
return acl;
}
static ushort ToUInt16 (byte[] buffer, int offset)
{
return (ushort)(buffer [offset] | buffer [offset + 1]);
}
[Test]
public void InheritanceFlagsMergeForAccessMasksThatMatch ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BU");
RawAcl acl = MakeRawAcl (new GenericAce[] {
new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 1, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, acl);
Assert.AreEqual (1, dacl.Count);
CommonAce ace = (CommonAce) dacl [0];
Assert.AreEqual (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, ace.InheritanceFlags);
}
[Test]
public void InheritanceFlagsDoNotMergeForAccessMasksThatAND ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BU");
RawAcl acl = MakeRawAcl (new GenericAce[] {
new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 3, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, acl);
Assert.AreEqual (2, dacl.Count);
}
[Test]
public void InheritanceFlagsAreClearedBeforeMergeCheckingWhenNotContainer ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BU");
RawAcl acl = MakeRawAcl (new GenericAce[] {
new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 2, sid, false, null)
});
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
Assert.AreEqual (1, dacl.Count);
CommonAce ace = (CommonAce) dacl [0];
Assert.AreEqual (3, ace.AccessMask);
Assert.AreEqual (InheritanceFlags.None, ace.InheritanceFlags);
}
}
}

View File

@@ -0,0 +1,253 @@
// CommonObjectSecurityTest.cs - NUnit Test Cases for CommonObjectSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 CommonObjectSecurityTest
{
[Test]
public void Defaults ()
{
TestSecurity security;
security = new TestSecurity (false);
Assert.IsFalse (security.IsContainerTest);
Assert.IsFalse (security.IsDSTest);
security = new TestSecurity (true);
Assert.IsTrue (security.IsContainerTest);
Assert.IsFalse (security.IsDSTest);
}
[Test]
public void AddAndGetAccessRulesWorkAndMergeCorrectly ()
{
var security = new TestSecurity (false);
// CommonObjectSecurity does not appear to care at all about types on MS.NET.
// It just uses AccessMask, and then GetAccessRules uses the factory methods.
// So, the whole API is a mess of strong typing and repeated code backed by nothing.
Assert.IsFalse (security.modify_access_called);
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
security.AddAccessRuleTest (new TestAccessRule<int> (sid, 2, AccessControlType.Allow));
security.AddAccessRuleTest (new TestAccessRule<TestRights> (sid, TestRights.One, AccessControlType.Allow));
security.AddAccessRuleTest (new TestAccessRule<int> (sid, 4, AccessControlType.Allow));
Assert.IsTrue (security.modify_access_called);
Assert.IsFalse (security.modify_access_rule_called);
Assert.IsFalse (security.modify_audit_called);
Assert.IsFalse (security.access_rule_factory_called);
AuthorizationRuleCollection rules1 = security.GetAccessRules (false, true, typeof (SecurityIdentifier));
Assert.IsFalse (security.access_rule_factory_called);
Assert.AreEqual (0, rules1.Count);
Assert.IsFalse (security.access_rule_factory_called);
AuthorizationRuleCollection rules2 = security.GetAccessRules (true, true, typeof (SecurityIdentifier));
Assert.IsTrue (security.access_rule_factory_called);
Assert.AreEqual (1, rules2.Count);
Assert.IsInstanceOfType (typeof (TestAccessRule<TestRights>), rules2[0]);
TestAccessRule<TestRights> rule = (TestAccessRule<TestRights>)rules2[0];
Assert.AreEqual ((TestRights)7, rule.Rights);
}
[Test]
public void AddAndPurgeWorks ()
{
TestSecurity security = new TestSecurity (false);
NTAccount nta1 = new NTAccount(@"BUILTIN\Users");
NTAccount nta2 = new NTAccount(@"BUILTIN\Administrators");
security.AddAccessRuleTest (new TestAccessRule<TestRights> (nta1, TestRights.One,
AccessControlType.Allow));
security.AddAccessRuleTest (new TestAccessRule<TestRights> (nta2, TestRights.One,
AccessControlType.Allow));
AuthorizationRuleCollection rules1 = security.GetAccessRules (true, true, typeof (NTAccount));
Assert.AreEqual (2, rules1.Count);
security.PurgeAccessRules (nta1);
AuthorizationRuleCollection rules2 = security.GetAccessRules (true, true, typeof (NTAccount));
Assert.AreEqual (1, rules2.Count);
Assert.IsInstanceOfType (typeof (TestAccessRule<TestRights>), rules2[0]);
TestAccessRule<TestRights> rule = (TestAccessRule<TestRights>)rules2[0];
Assert.AreEqual (nta2, rule.IdentityReference);
}
[Test]
public void ResetAccessRuleCausesExactlyOneModifyAccessCall ()
{
TestSecurity security = new TestSecurity (false);
SecurityIdentifier sid = new SecurityIdentifier ("WD");
security.ResetAccessRuleTest (new TestAccessRule<TestRights> (sid, TestRights.One,
AccessControlType.Allow));
Assert.AreEqual (1, security.modify_access_called_count);
}
class TestAccessRule<T> : AccessRule
{
public TestAccessRule (IdentityReference identity, T rules,
AccessControlType type)
: this (identity, rules, InheritanceFlags.None, PropagationFlags.None, type)
{
}
public TestAccessRule (IdentityReference identity, T rules,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
AccessControlType type)
: base (identity, (int)(object)rules, false, inheritanceFlags, propagationFlags, type)
{
}
public T Rights {
get { return (T)(object)AccessMask; }
}
}
class TestAuditRule<T> : AuditRule
{
public TestAuditRule (IdentityReference identity, T rules,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
AuditFlags auditFlags)
: base (identity, (int)(object)rules, false, inheritanceFlags, propagationFlags, auditFlags)
{
}
}
enum TestRights
{
One = 1
}
class TestSecurity : CommonObjectSecurity
{
public bool access_rule_factory_called;
public bool audit_rule_factory_called;
public bool modify_access_called;
public int modify_access_called_count;
public bool modify_access_rule_called;
public bool modify_audit_called;
public bool modify_audit_rule_called;
public TestSecurity (bool isContainer)
: base (isContainer)
{
}
public bool IsContainerTest {
get { return IsContainer; }
}
public bool IsDSTest {
get { return IsDS; }
}
public void AddAccessRuleTest (AccessRule rule)
{
AddAccessRule (rule);
}
public void AddAuditRuleTest (AuditRule rule)
{
AddAuditRule (rule);
}
public bool RemoveAccessRuleTest (AccessRule rule)
{
return RemoveAccessRule (rule);
}
public void RemoveAccessRuleAllTest (AccessRule rule)
{
RemoveAccessRuleAll (rule);
}
public void RemoveAccessRuleSpecificTest (AccessRule rule)
{
RemoveAccessRuleSpecific (rule);
}
public void ResetAccessRuleTest (AccessRule rule)
{
ResetAccessRule (rule);
}
public override AccessRule AccessRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags,
AccessControlType type)
{
access_rule_factory_called = true;
return new TestAccessRule<TestRights> (identityReference, (TestRights)accessMask,
inheritanceFlags, propagationFlags, type);
}
public override AuditRule AuditRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags,
AuditFlags flags)
{
audit_rule_factory_called = true;
return new TestAuditRule<TestRights> (identityReference, (TestRights)accessMask,
inheritanceFlags, propagationFlags, flags);
}
public override bool ModifyAccessRule (AccessControlModification modification,
AccessRule rule, out bool modified)
{
modify_access_rule_called = true;
return base.ModifyAccessRule (modification, rule, out modified);
}
protected override bool ModifyAccess (AccessControlModification modification,
AccessRule rule, out bool modified)
{
modify_access_called = true;
modify_access_called_count ++;
return base.ModifyAccess (modification, rule, out modified);
}
public override bool ModifyAuditRule (AccessControlModification modification,
AuditRule rule, out bool modified)
{
modify_audit_rule_called = true;
return base.ModifyAuditRule (modification, rule, out modified);
}
protected override bool ModifyAudit (AccessControlModification modification,
AuditRule rule, out bool modified)
{
modify_audit_called = true;
return base.ModifyAudit (modification, rule, out modified);
}
public override Type AccessRightType {
get { return typeof (TestRights); }
}
public override Type AccessRuleType {
get { return typeof (TestAccessRule<TestRights>); }
}
public override Type AuditRuleType {
get { return typeof (TestAuditRule<TestRights>); }
}
}
}
}

View File

@@ -0,0 +1,396 @@
// CommonSecurityDescriptorTest.cs - NUnit Test Cases for CommonSecurityDescriptor
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 CommonSecurityDescriptorTest
{
[Test]
public void DefaultOwnerAndGroup ()
{
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
Assert.IsNull (csd.Owner);
Assert.IsNull (csd.Group);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative, csd.ControlFlags);
}
[Test]
public void GetBinaryForm ()
{
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
Assert.AreEqual (20, csd.BinaryLength);
byte[] binaryForm = new byte[csd.BinaryLength];
csd.GetBinaryForm (binaryForm, 0);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative,
csd.ControlFlags);
// The default 'Allow Everyone Full Access' serializes as NOT having a
// DiscretionaryAcl, as the above demonstrates (byte 3 is 0 not 4).
Assert.AreEqual (new byte[20] {
1, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}, binaryForm);
// Changing SystemAcl protection does nothing special.
csd.SetSystemAclProtection (true, true);
Assert.AreEqual (20, csd.BinaryLength);
// Modifying the DiscretionaryAcl (even effective no-ops like this) causes serialization.
csd.SetDiscretionaryAclProtection (false, true);
Assert.AreEqual (48, csd.BinaryLength);
}
[Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
public void GetBinaryFormOffset ()
{
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
csd.GetBinaryForm (new byte[csd.BinaryLength], 1);
}
[Test, ExpectedException (typeof (ArgumentNullException))]
public void GetBinaryFormNull ()
{
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
csd.GetBinaryForm (null, 0);
}
[Test]
public void AefaModifiedFlagIsStoredOnDiscretionaryAcl ()
{
CommonSecurityDescriptor csd1, csd2;
// Incidentally this shows the DiscretionaryAcl is NOT cloned.
csd1 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
csd2 = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, csd1.DiscretionaryAcl);
Assert.AreSame (csd1.DiscretionaryAcl, csd2.DiscretionaryAcl);
Assert.AreEqual ("", csd1.GetSddlForm (AccessControlSections.Access));
csd2.SetDiscretionaryAclProtection (false, true);
Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd1.GetSddlForm (AccessControlSections.Access));
Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd2.GetSddlForm (AccessControlSections.Access));
}
[Test]
public void AefaRoundtrip ()
{
CommonSecurityDescriptor csd;
csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, null, null, null, null);
Assert.AreEqual (20, csd.BinaryLength);
byte[] binaryForm1 = new byte[csd.BinaryLength];
csd.GetBinaryForm (binaryForm1, 0);
csd = new CommonSecurityDescriptor (false, false, new RawSecurityDescriptor (binaryForm1, 0));
byte[] binaryForm2 = new byte[csd.BinaryLength];
csd.GetBinaryForm (binaryForm2, 0);
Assert.AreEqual (binaryForm1, binaryForm2);
}
[Test]
public void GetSddlFormAefaRemovesDacl ()
{
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative,
csd.ControlFlags);
Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
Assert.AreEqual ("", csd.GetSddlForm (AccessControlSections.Access));
csd.SetDiscretionaryAclProtection (false, true);
Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
Assert.AreSame (csd.DiscretionaryAcl, csd.DiscretionaryAcl);
Assert.AreNotSame (csd.DiscretionaryAcl[0], csd.DiscretionaryAcl[0]);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative,
csd.ControlFlags);
csd.SetDiscretionaryAclProtection (true, true);
Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
Assert.AreEqual ("D:P(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.DiscretionaryAclProtected
| ControlFlags.SelfRelative,
csd.ControlFlags);
csd.SetDiscretionaryAclProtection (false, false);
Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
Assert.AreEqual ("D:(A;;0xffffffff;;;WD)", csd.GetSddlForm (AccessControlSections.Access));
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative,
csd.ControlFlags);
}
[Test, ExpectedException (typeof (ArgumentException))]
public void ContainerAndDSConsistencyEnforcedA ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
DiscretionaryAcl dacl = new DiscretionaryAcl (true, true, 0);
new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, dacl);
}
[Test, ExpectedException (typeof (ArgumentException))]
public void ContainerAndDSConsistencyEnforcedB ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
SystemAcl sacl = new SystemAcl (false, false, 0);
new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, sacl, null);
}
[Test, ExpectedException (typeof (ArgumentException))]
public void ContainerAndDSConsistencyEnforcedInSetter ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(true, false, ControlFlags.None, userSid, groupSid, null, null);
csd.DiscretionaryAcl = new DiscretionaryAcl (true, true, 0);
}
[Test]
public void DefaultDaclIsAllowEveryoneFullAccess ()
{
SecurityIdentifier userSid = new SecurityIdentifier ("SY");
SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD");
CommonSecurityDescriptor csd; DiscretionaryAcl dacl; CommonAce ace;
csd = new CommonSecurityDescriptor (false, false, ControlFlags.None, userSid, groupSid, null, null);
dacl = csd.DiscretionaryAcl;
Assert.AreEqual (1, dacl.Count);
ace = (CommonAce)dacl [0];
Assert.AreEqual (-1, ace.AccessMask);
Assert.AreEqual (AceFlags.None, ace.AceFlags);
Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
Assert.AreEqual (20, ace.BinaryLength);
Assert.IsFalse (ace.IsCallback);
Assert.IsFalse (ace.IsInherited);
Assert.AreEqual (0, ace.OpaqueLength);
Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
csd = new CommonSecurityDescriptor (true, false, ControlFlags.None, userSid, groupSid, null, null);
dacl = csd.DiscretionaryAcl;
Assert.AreEqual (1, dacl.Count);
ace = (CommonAce)dacl [0];
Assert.AreEqual (-1, ace.AccessMask);
Assert.AreEqual (AceFlags.ObjectInherit | AceFlags.ContainerInherit, ace.AceFlags);
Assert.AreEqual (AceType.AccessAllowed, ace.AceType);
Assert.AreEqual (20, ace.BinaryLength);
Assert.IsFalse (ace.IsCallback);
Assert.IsFalse (ace.IsInherited);
Assert.AreEqual (0, ace.OpaqueLength);
Assert.AreEqual (ace.SecurityIdentifier, everyoneSid);
}
[Test]
public void PurgeDefaultDacl ()
{
SecurityIdentifier userSid = new SecurityIdentifier ("SY");
SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
SecurityIdentifier everyoneSid = new SecurityIdentifier ("WD");
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
DiscretionaryAcl dacl = csd.DiscretionaryAcl;
Assert.AreEqual (1, dacl.Count);
csd.PurgeAccessControl (userSid);
Assert.AreEqual (1, dacl.Count);
csd.PurgeAccessControl (everyoneSid);
Assert.AreEqual (0, dacl.Count);
}
[Test]
public void PurgeNullSaclWithoutError ()
{
SecurityIdentifier userSid = new SecurityIdentifier ("SY");
SecurityIdentifier groupSid = new SecurityIdentifier ("BA");
CommonSecurityDescriptor csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
csd.PurgeAudit (userSid);
Assert.IsNull (csd.SystemAcl);
}
[Test]
public void OwnerAndGroupAreReferences ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonSecurityDescriptor csd;
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
Assert.AreSame (groupSid, csd.Group);
Assert.AreSame (userSid, csd.Owner);
}
[Test]
public void ProtectionChangesFlags ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonSecurityDescriptor csd;
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative, csd.ControlFlags);
csd.SetDiscretionaryAclProtection (true, false);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.DiscretionaryAclProtected
| ControlFlags.SelfRelative, csd.ControlFlags);
csd.SetSystemAclProtection (true, false); // despite not being *present*
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.DiscretionaryAclProtected
| ControlFlags.SystemAclProtected
| ControlFlags.SelfRelative, csd.ControlFlags);
}
[Test]
public void ProtectionPreserveInheritanceIgnoredUnlessProtectedTrue ()
{
CommonSecurityDescriptor descriptor;
descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
descriptor.SetDiscretionaryAclProtection (true, false);
Assert.AreEqual (1, descriptor.DiscretionaryAcl.Count);
descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
descriptor.SetDiscretionaryAclProtection (false, false);
Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
descriptor = ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor();
descriptor.SetDiscretionaryAclProtection (true, true);
Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
descriptor.SetDiscretionaryAclProtection (false, false);
Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
descriptor.SetDiscretionaryAclProtection (false, true);
Assert.AreEqual (2, descriptor.DiscretionaryAcl.Count);
descriptor.SetDiscretionaryAclProtection (true, false);
Assert.AreEqual (1, descriptor.DiscretionaryAcl.Count);
}
static CommonSecurityDescriptor ProtectionPreserveInheritanceIgnoredUnlessProtectedTrueDescriptor()
{
SecurityIdentifier sid = new SecurityIdentifier ("WD");
RawAcl acl = new RawAcl (GenericAcl.AclRevision, 1);
acl.InsertAce (0, new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null));
acl.InsertAce (1, new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid, false, null));
CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
descriptor.DiscretionaryAcl = new DiscretionaryAcl (false, false, acl);
return descriptor;
}
[Test]
public void DaclPresent ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonSecurityDescriptor csd;
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
Assert.IsNotNull (csd.DiscretionaryAcl);
Assert.IsTrue (csd.IsDiscretionaryAclCanonical);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
Assert.AreEqual (1, csd.DiscretionaryAcl.Count);
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.DiscretionaryAclPresent, userSid, groupSid, null, null);
Assert.IsNotNull (csd.DiscretionaryAcl);
Assert.IsTrue (csd.IsDiscretionaryAclCanonical);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, dacl);
Assert.AreSame (dacl, csd.DiscretionaryAcl);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.DiscretionaryAclPresent, userSid, groupSid, null, dacl);
Assert.AreSame (dacl, csd.DiscretionaryAcl);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
}
[Test]
public void SaclPresent ()
{
SecurityIdentifier userSid = new SecurityIdentifier (WellKnownSidType.LocalSystemSid, null);
SecurityIdentifier groupSid = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
SystemAcl sacl = new SystemAcl (false, false, 0);
CommonSecurityDescriptor csd;
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, null, null);
Assert.IsNull (csd.SystemAcl);
Assert.IsTrue (csd.IsSystemAclCanonical);
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.SystemAclPresent, userSid, groupSid, null, null);
Assert.IsNull (csd.SystemAcl);
Assert.IsTrue (csd.IsSystemAclCanonical);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent | ControlFlags.SelfRelative, csd.ControlFlags);
csd = new CommonSecurityDescriptor
(false, false, ControlFlags.None, userSid, groupSid, sacl, null);
Assert.AreSame (sacl, csd.SystemAcl);
Assert.IsTrue (csd.IsSystemAclCanonical);
Assert.AreEqual (0, csd.SystemAcl.Count);
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SystemAclPresent
| ControlFlags.SelfRelative, csd.ControlFlags);
csd.SystemAcl = null;
Assert.AreEqual (ControlFlags.DiscretionaryAclPresent
| ControlFlags.SelfRelative, csd.ControlFlags);
}
}
}

View File

@@ -0,0 +1,38 @@
// CryptoKeyAccessRuleTest.cs - NUnit Test Cases for CryptoKeyAccessRule
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 CryptoKeyAccessRuleTest
{
[Test]
public void StringOverloadIsNTAccount ()
{
CryptoKeyAccessRule rule;
rule = new CryptoKeyAccessRule (@"BUILTIN\Users", CryptoKeyRights.FullControl, AccessControlType.Allow);
Assert.AreNotEqual (new SecurityIdentifier ("BU"), rule.IdentityReference);
Assert.AreEqual (new NTAccount (@"BUILTIN\Users"), rule.IdentityReference);
}
[Test]
public void StringOverloadIsNotSID ()
{
CryptoKeyAccessRule rule;
rule = new CryptoKeyAccessRule (@"S-1-5-32-545", CryptoKeyRights.FullControl, AccessControlType.Allow);
Assert.AreNotEqual (new SecurityIdentifier ("S-1-5-32-545"), rule.IdentityReference);
Assert.AreEqual (new NTAccount (@"S-1-5-32-545"), rule.IdentityReference);
}
}
}

View File

@@ -0,0 +1,240 @@
// DirectoryObjectSecurityTest.cs - NUnit Test Cases for DirectoryObjectSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 DirectoryObjectSecurityTest
{
[Test]
public void Defaults ()
{
TestSecurity security = new TestSecurity ();
Assert.IsTrue (security.IsContainerTest);
Assert.IsTrue (security.IsDSTest);
}
[Test, ExpectedExceptionAttribute (typeof (ArgumentOutOfRangeException))]
public void ChecksAccessControlModificationRange ()
{
bool modifiedRet, modifiedOut;
TestSecurity security = new TestSecurity ();
SecurityIdentifier sid = new SecurityIdentifier ("WD");
TestAccessRule rule = new TestAccessRule
(sid, 1, false, InheritanceFlags.None, PropagationFlags.None,
Guid.Empty, Guid.Empty, AccessControlType.Allow);
modifiedRet = security.ModifyAccessRule ((AccessControlModification)43210,
rule, out modifiedOut);
}
[Test]
public void IgnoresResetOnAuditAndReturnsTrue ()
{
bool modifiedRet, modifiedOut;
TestSecurity security = new TestSecurity ();
SecurityIdentifier sid = new SecurityIdentifier ("WD");
TestAuditRule rule = new TestAuditRule
(sid, 1, false, InheritanceFlags.None, PropagationFlags.None,
Guid.Empty, Guid.Empty, AuditFlags.Success);
modifiedRet = security.ModifyAuditRule (AccessControlModification.Reset,
rule, out modifiedOut);
Assert.IsTrue (modifiedRet);
}
[Test, ExpectedException (typeof (ArgumentNullException))]
public void ConstructorFailsOnNullDescriptor ()
{
new TestSecurity (null);
}
[Test]
public void ConstructorLetsFalseDSThrough ()
{
CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
TestSecurity security = new TestSecurity (descriptor);
Assert.IsFalse (security.IsContainerTest);
Assert.IsFalse (security.IsDSTest);
}
[Test]
public void ObjectSecurityJustWrapsCommonSecurityDescriptor ()
{
CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
(false, false, ControlFlags.None, null, null, null, null);
TestSecurity security = new TestSecurity (descriptor);
Assert.IsNull (security.GetOwner (typeof(SecurityIdentifier)));
SecurityIdentifier sid = new SecurityIdentifier ("WD");
descriptor.Owner = sid; // Not virtual, so the conclusion in the test's title.
Assert.IsFalse (security.OwnerModifiedTest);
Assert.AreSame (sid, security.GetOwner (typeof(SecurityIdentifier)));
security.SetOwner (sid);
Assert.IsTrue (security.OwnerModifiedTest);
Assert.AreSame (sid, security.GetOwner (typeof(SecurityIdentifier)));
}
[Test, ExpectedExceptionAttribute (typeof (InvalidOperationException))]
public void LocksAreEnforced ()
{
TestSecurity security = new TestSecurity ();
bool value = security.OwnerModifiedTestWithoutLock;
}
[Test]
[Category ("NotWorking")] // Mono does not have a working CustomAce implementation yet.
public void ObjectSecurityRemovesWhatItCannotCreate ()
{
RawAcl acl = new RawAcl (GenericAcl.AclRevision, 1);
acl.InsertAce (0, new CustomAce ((AceType)255, AceFlags.None, new byte[4]));
DiscretionaryAcl dacl = new DiscretionaryAcl (true, true, acl);
Assert.AreEqual (1, dacl.Count);
CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
(true, true, ControlFlags.None, null, null, null, dacl);
TestSecurity security = new TestSecurity (descriptor);
AuthorizationRuleCollection rules = security.GetAccessRules (true, true, typeof (SecurityIdentifier));
Assert.AreEqual (0, rules.Count);
}
[Test]
public void FactoryWithoutGuidsCalledWhenNotObjectAce ()
{
TestSecurity security = FactoryCallTest (false);
Assert.IsTrue (security.access_factory_called);
}
[Test, ExpectedExceptionAttribute (typeof (NotImplementedException))]
public void FactoryWithGuidsThrowsNotImplementedByDefault ()
{
FactoryCallTest (true);
}
TestSecurity FactoryCallTest (bool objectAce)
{
SecurityIdentifier sid = new SecurityIdentifier ("WD");
DiscretionaryAcl dacl = new DiscretionaryAcl (true, true, 1);
dacl.AddAccess (AccessControlType.Allow, sid, 1,
InheritanceFlags.None, PropagationFlags.None,
objectAce ? ObjectAceFlags.ObjectAceTypePresent : ObjectAceFlags.None,
Guid.NewGuid (), Guid.Empty);
CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor
(true, true, ControlFlags.None, null, null, null, dacl);
TestSecurity security = new TestSecurity (descriptor);
security.GetAccessRules (true, true, typeof (SecurityIdentifier));
return security;
}
class TestAccessRule : ObjectAccessRule
{
public TestAccessRule(IdentityReference identity, int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
Guid objectType, Guid inheritedObjectType,
AccessControlType type)
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags,
objectType, inheritedObjectType, type)
{
}
}
class TestAuditRule : ObjectAuditRule
{
public TestAuditRule(IdentityReference identity, int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags,
Guid objectType, Guid inheritedObjectType,
AuditFlags flags)
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags,
objectType, inheritedObjectType, flags)
{
}
}
class TestSecurity : DirectoryObjectSecurity
{
internal bool access_factory_called;
public TestSecurity ()
{
}
public TestSecurity (CommonSecurityDescriptor descriptor)
: base (descriptor)
{
}
public bool IsContainerTest {
get { return IsContainer; }
}
public bool IsDSTest {
get { return IsDS; }
}
public bool OwnerModifiedTest {
get { ReadLock (); bool value = OwnerModified; ReadUnlock (); return value; }
set { WriteLock (); OwnerModified = value; WriteUnlock (); }
}
public bool OwnerModifiedTestWithoutLock {
get { return OwnerModified; }
}
public override AccessRule AccessRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags,
AccessControlType type)
{
access_factory_called = true;
return new TestAccessRule (identityReference, accessMask,
isInherited, inheritanceFlags, propagationFlags,
Guid.Empty, Guid.Empty, type);
}
public override AuditRule AuditRuleFactory (IdentityReference identityReference,
int accessMask, bool isInherited,
InheritanceFlags inheritanceFlags,
PropagationFlags propagationFlags,
AuditFlags flags)
{
return new TestAuditRule (identityReference, accessMask,
isInherited, inheritanceFlags, propagationFlags,
Guid.Empty, Guid.Empty, flags);
}
public override Type AccessRightType {
get { return typeof (int); }
}
public override Type AccessRuleType {
get { return typeof (TestAccessRule); }
}
public override Type AuditRuleType {
get { return typeof (TestAuditRule); }
}
}
}
}

View File

@@ -0,0 +1,109 @@
// DirectorySecurityTest.cs - NUnit Test Cases for DirectorySecurity
//
// Authors:
// James Bellinger (jfb@zer7.com)
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class DirectorySecurityTest
{
[Test]
public void InheritedPermissions ()
{
AuthorizationRuleCollection rules;
DirectorySecurity dirSecurity; FileSecurity fileSecurity;
SecurityIdentifier usersSid = new SecurityIdentifier ("BU");
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
FileSystemAccessRule worldDirFullControl = new FileSystemAccessRule
(worldSid, FileSystemRights.FullControl,
InheritanceFlags.ObjectInherit, PropagationFlags.None,
AccessControlType.Allow);
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string dirpath = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName ());
string dirpath2 = null;
string filepath = null;
DirectoryInfo dirinfo = Directory.CreateDirectory (dirpath);
try {
// Set Full Control to Everyone.
dirSecurity = dirinfo.GetAccessControl ();
dirSecurity.SetGroup (usersSid);
dirSecurity.AddAccessRule (worldDirFullControl);
Directory.SetAccessControl (dirpath, dirSecurity);
// Did the rule store on the directory?
dirSecurity = Directory.GetAccessControl (dirpath);
rules = dirSecurity.GetAccessRules (true, false, typeof (SecurityIdentifier ));
Assert.AreEqual (usersSid, dirSecurity.GetGroup (typeof(SecurityIdentifier)));
Assert.AreEqual (1, rules.Count);
Assert.AreEqual (worldSid, rules[0].IdentityReference);
Assert.AreEqual (InheritanceFlags.ObjectInherit, rules[0].InheritanceFlags);
Assert.AreEqual (PropagationFlags.None, rules[0].PropagationFlags);
Assert.IsFalse (rules[0].IsInherited);
// Create a file. It will have no explicit rules.
filepath = Path.Combine (dirpath, Path.GetRandomFileName ());
using (FileStream file = new FileStream (filepath, FileMode.Create, FileAccess.ReadWrite)) {
fileSecurity = file.GetAccessControl ();
rules = fileSecurity.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (0, rules.Count);
}
// Make sure the file has inherited the Full Control access rule.
FileInfo fileInfo = new FileInfo (filepath);
fileSecurity = fileInfo.GetAccessControl ();
rules = fileSecurity.GetAccessRules (false, true, typeof (SecurityIdentifier));
bool fileInheritedRule = false;
foreach (FileSystemAccessRule rule in rules) {
if (rule.AccessControlType == AccessControlType.Allow &&
rule.FileSystemRights == FileSystemRights.FullControl &&
rule.IdentityReference == worldSid &&
rule.IsInherited &&
rule.InheritanceFlags == InheritanceFlags.None &&
rule.PropagationFlags == PropagationFlags.None) // only containers get non-None flags
fileInheritedRule = true;
}
Assert.IsTrue (fileInheritedRule);
// ContainerInherit not being set, create a directory.
// Its inherited rule will have propagation flags to indicate only its children are affected.
dirpath2 = Path.Combine (dirpath, Path.GetRandomFileName ());
dirinfo = Directory.CreateDirectory (dirpath2);
dirSecurity = dirinfo.GetAccessControl ();
rules = dirSecurity.GetAccessRules (false, true, typeof (SecurityIdentifier));
bool dirInheritedRule = false;
foreach (FileSystemAccessRule rule in rules) {
if (rule.AccessControlType == AccessControlType.Allow &&
rule.FileSystemRights == FileSystemRights.FullControl &&
rule.IdentityReference == worldSid &&
rule.IsInherited &&
rule.InheritanceFlags == InheritanceFlags.ObjectInherit &&
rule.PropagationFlags == PropagationFlags.InheritOnly) // <-- key difference
dirInheritedRule = true;
}
Assert.IsTrue (dirInheritedRule);
} finally {
if (null != filepath) File.Delete (filepath);
if (null != dirpath2) Directory.Delete (dirpath2);
Directory.Delete (dirpath);
}
}
}
}

View File

@@ -0,0 +1,249 @@
// DiscretionaryAclTest.cs - NUnit Test Cases for DiscretionaryAcl
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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);
}
}
}

View File

@@ -0,0 +1,68 @@
// EventWaitHandleSecurityTest.cs - NUnit Test Cases for EventWaitHandleSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// Copyright (C) 2012 James Bellinger
using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class EventWaitHandleSecurityTest
{
// TODO: Mono System.Threading.EventWaitHandle does not throw exceptions on failure!
[Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
public void PermissionsActuallyWork ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
bool createdNew; EventWaitHandleSecurity security;
string name = @"Local\MonoTestWaitHandle";
using (EventWaitHandle handle = new EventWaitHandle (false, EventResetMode.ManualReset,
name, out createdNew)) {
Assert.IsFalse (handle.SafeWaitHandle.IsInvalid);
Assert.IsTrue (createdNew);
// Make sure our later error will be due to permissions and not some sharing bug.
bool createdAnotherNew;
using (EventWaitHandle anotherHandle = new EventWaitHandle (false, EventResetMode.ManualReset,
name, out createdAnotherNew)) {
Assert.IsFalse (anotherHandle.SafeWaitHandle.IsInvalid);
Assert.IsFalse (createdAnotherNew);
}
// Let's make a deny all.
security = handle.GetAccessControl ();
foreach (EventWaitHandleAccessRule rule in security.GetAccessRules
(true, false, typeof (SecurityIdentifier))) {
security.RemoveAccessRuleSpecific (rule);
}
Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
handle.SetAccessControl (security);
security = handle.GetAccessControl ();
Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
// MS.NET will throw on the first line below.
// For Mono testing the latter verifies the rest until the EventWaitHandle bug is fixed.
// Also, NUnit 2.4 appears to lacks Assert.Pass ().
EventWaitHandle badHandle = new EventWaitHandle(false, EventResetMode.ManualReset, name);
if (badHandle.SafeWaitHandle.IsInvalid)
throw new UnauthorizedAccessException ();
}
}
}
}

View File

@@ -0,0 +1,109 @@
// FileSecurityTest.cs - NUnit Test Cases for FileSecurity
//
// Authors:
// James Bellinger (jfb@zer7.com)
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class FileSecurityTest
{
[Test]
public void ChangeGroupToEveryone ()
{
FileSecurity security;
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string path = Path.GetTempFileName ();
try {
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
security = File.GetAccessControl (path);
security.SetGroup (worldSid);
File.SetAccessControl (path, security);
security = File.GetAccessControl (path);
Assert.AreEqual (worldSid, security.GetGroup (typeof(SecurityIdentifier)));
} finally {
File.Delete (path);
}
}
[Test]
public void ChangeAccessRules ()
{
FileSecurity security;
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string path = Path.GetTempFileName ();
try {
// Add 'Everyone' to the access list.
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
security = File.GetAccessControl (path);
FileSystemAccessRule rule = new FileSystemAccessRule (worldSid,
FileSystemRights.FullControl,
AccessControlType.Allow);
security.AddAccessRule (rule);
File.SetAccessControl (path, security);
// Make sure 'Everyone' is *on* the access list.
// Let's use the SafeHandle overload to check it.
AuthorizationRuleCollection rules;
using (FileStream file = File.Open (path, FileMode.Open, FileAccess.Read)) {
security = file.GetAccessControl ();
rules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (1, rules.Count);
Assert.AreEqual (worldSid, rules[0].IdentityReference);
Assert.AreEqual (InheritanceFlags.None, rules[0].InheritanceFlags);
Assert.AreEqual (PropagationFlags.None, rules[0].PropagationFlags);
Assert.IsFalse (rules[0].IsInherited);
}
// Remove 'Everyone' from the access list.
security.RemoveAccessRuleSpecific (rule);
File.SetAccessControl (path, security);
// Make sure our non-inherited access control list is now empty.
security = File.GetAccessControl (path);
rules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (0, rules.Count);
} finally {
File.Delete (path);
}
}
[Test, ExpectedException (typeof (InvalidOperationException))]
public void EveryoneMayNotBeOwner ()
{
FileSecurity security;
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string path = Path.GetTempFileName ();
try {
security = File.GetAccessControl (path);
security.SetOwner (new SecurityIdentifier ("WD"));
File.SetAccessControl (path, security);
} finally {
File.Delete (path);
}
}
}
}

View File

@@ -0,0 +1,25 @@
// MutexAccessRuleTest - NUnit Test Cases for MutexAccessRule
//
// Authors:
// James Bellinger (jfb@zer7.com)
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class MutexAccessRuleTest
{
[Test]
public void ConstructsWithoutCrashingAndRemembersRights ()
{
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
MutexAccessRule rule = new MutexAccessRule (id, MutexRights.FullControl, AccessControlType.Allow);
Assert.AreEqual (rule.MutexRights, MutexRights.FullControl);
}
}
}

View File

@@ -0,0 +1,145 @@
// MutexSecurityTest.cs - NUnit Test Cases for MutexSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// Copyright (C) 2012 James Bellinger
#if !MOBILE
using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class MutexSecurityTest
{
[Test, ExpectedException (typeof (WaitHandleCannotBeOpenedException))]
public void FailsForNonexistantMutex ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
new MutexSecurity (@"Local\NonexistantMutex", AccessControlSections.Access);
}
[Test]
public void SucceedsForExistingMutex ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
bool createdNew;
string name = @"Local\MonoTestMutex";
// Let's be sure the mutex destroys on Close() as well.
// Otherwise, many of our tests will fail as they will be accessing the wrong mutex.
using (Mutex mutex = new Mutex (false, name, out createdNew)) {
Assert.IsTrue (createdNew);
new MutexSecurity (name, AccessControlSections.Access);
}
using (Mutex mutex = new Mutex (false, name, out createdNew)) {
Assert.IsTrue (createdNew);
new MutexSecurity (name, AccessControlSections.Access);
}
}
[Test]
public void CanSetAndGetMutexSecurity ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
MutexAccessRule rule; SecurityIdentifier sid;
AuthorizationRuleCollection rulesA, rulesB, rulesC;
bool createdNew; MutexSecurity security;
string name = @"Local\MonoTestMutex";
using (Mutex mutex = new Mutex(false, name, out createdNew)) {
Assert.IsTrue (createdNew);
security = mutex.GetAccessControl ();
rulesA = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreNotEqual (0, rulesA.Count);
// Contrary to what you'd expect, these classes only try to persist sections that
// that were *changed*. Awful, eh? To be fair, if you retrieve and modify it's fine.
security = new MutexSecurity ();
mutex.SetAccessControl (security);
security = mutex.GetAccessControl ();
rulesB = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (rulesA.Count, rulesB.Count);
// And here's our dummy change. Observe...
sid = new SecurityIdentifier( "S-1-5-12-3456-7890");
rule = new MutexAccessRule (sid, MutexRights.Synchronize, AccessControlType.Allow);
security = new MutexSecurity ();
security.RemoveAccessRuleSpecific (rule);
mutex.SetAccessControl (security);
security = mutex.GetAccessControl ();
rulesC = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (0, rulesC.Count);
}
}
// TODO: Mono System.Threading.Mutex does not throw exceptions on failure!
[Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
public void PermissionsActuallyWork ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
bool createdNew; MutexSecurity security;
string name = @"Local\MonoTestMutex";
using (Mutex mutex = new Mutex (false, name, out createdNew)) {
Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
Assert.IsTrue (createdNew);
// Make sure our later error will be due to permissions and not some sharing bug.
bool createdAnotherNew;
using (Mutex anotherMutex = new Mutex (false, name, out createdAnotherNew)) {
Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
Assert.IsFalse (createdAnotherNew);
}
// Let's make a deny all.
security = mutex.GetAccessControl ();
foreach (MutexAccessRule rule in security.GetAccessRules
(true, false, typeof (SecurityIdentifier))) {
security.RemoveAccessRuleSpecific (rule);
}
Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
mutex.SetAccessControl (security);
security = mutex.GetAccessControl ();
Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
// MS.NET will throw on the first line below.
// For Mono testing the latter verifies the rest until the Mutex bug is fixed.
// Also, NUnit 2.4 appears to lacks Assert.Pass ().
Mutex badMutex = new Mutex(false, name);
if (badMutex.SafeWaitHandle.IsInvalid)
throw new UnauthorizedAccessException ();
}
}
}
}
#endif

View File

@@ -0,0 +1,119 @@
// ObjectAceTest.cs - NUnit Test Cases for ObjectAce
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 ObjectAceTest
{
static RawAcl CreateRoundtripRawAcl ()
{
SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
Assert.AreEqual (16, sid.BinaryLength);
GenericAce[] aces = new GenericAce[] {
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid,
ObjectAceFlags.ObjectAceTypePresent,
Guid.Empty, Guid.Empty, false, new byte[8]),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid,
ObjectAceFlags.InheritedObjectAceTypePresent,
Guid.Empty, Guid.Empty, true, new byte[16]),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid,
ObjectAceFlags.InheritedObjectAceTypePresent,
Guid.Empty, new Guid ("{8865FB90-A9EB-422F-A8BA-07ECA611D699}"), true, new byte[4]),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid,
ObjectAceFlags.ObjectAceTypePresent|ObjectAceFlags.InheritedObjectAceTypePresent,
Guid.Empty, new Guid ("{B893007C-38D5-4827-A698-BA25F1E30BAC}"), true, new byte[4]),
new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid,
ObjectAceFlags.None,
Guid.Empty, new Guid ("{C0F9DF22-C320-4400-B41F-754F69668640}"), true, new byte[4])
};
// Make sure this created right, first of all.
Assert.AreEqual (AceType.AccessAllowedObject, aces [0].AceType);
Assert.AreEqual (AceType.AccessAllowedCallbackObject, aces [1].AceType);
Assert.AreEqual (AceType.AccessAllowedCallbackObject, aces [2].AceType);
Assert.AreEqual (AceType.AccessAllowedCallbackObject, aces [3].AceType);
Assert.AreEqual (AceType.AccessAllowedCallbackObject, aces [4].AceType);
Assert.AreEqual (52, aces [0].BinaryLength);
Assert.AreEqual (60, aces [1].BinaryLength);
Assert.AreEqual (48, aces [2].BinaryLength);
Assert.AreEqual (64, aces [3].BinaryLength);
Assert.AreEqual (32, aces [4].BinaryLength);
RawAcl acl = new RawAcl (RawAcl.AclRevision, 0);
for (int i = 0; i < aces.Length; i ++)
acl.InsertAce (i, aces[i]);
return acl;
}
void CompareBinaryForms (byte[] binaryFormExpected, byte[] binaryFormActual)
{
Assert.AreEqual (binaryFormExpected.Length, binaryFormActual.Length);
for (int i = 0; i < binaryFormExpected.Length; i ++)
Assert.AreEqual (binaryFormExpected [i], binaryFormActual [i], "Mismatch at position " + i.ToString ());
}
[Test]
public void BinaryRoundtrip ()
{
RawAcl acl = CreateRoundtripRawAcl ();
byte[] binaryForm1 = new byte[acl.BinaryLength];
acl.GetBinaryForm (binaryForm1, 0);
RawAcl acl2 = new RawAcl (binaryForm1, 0);
byte[] binaryForm2 = new byte[acl2.BinaryLength];
acl2.GetBinaryForm (binaryForm2, 0);
CompareBinaryForms (binaryForm1, binaryForm2);
}
[Test] // This blob produced by binaryForm1 from the BinaryRoundtrip test...
public void BlobMatchesMSNet ()
{
RawAcl acl = CreateRoundtripRawAcl ();
byte[] binaryForm1 = new byte[acl.BinaryLength];
acl.GetBinaryForm (binaryForm1, 0);
byte[] binaryForm2 = new byte[] { // 11 per line
(byte)0x02, (byte)0x00, (byte)0x08, (byte)0x01, (byte)0x05, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x00, (byte)0x34,
(byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05,
(byte)0x20, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x21, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0B, (byte)0x00, (byte)0x3C, (byte)0x00, (byte)0x02, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x20, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x21, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0B,
(byte)0x00, (byte)0x30, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x90, (byte)0xFB, (byte)0x65, (byte)0x88, (byte)0xEB, (byte)0xA9, (byte)0x2F, (byte)0x42, (byte)0xA8, (byte)0xBA, (byte)0x07,
(byte)0xEC, (byte)0xA6, (byte)0x11, (byte)0xD6, (byte)0x99, (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x05, (byte)0x20, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x21, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0B, (byte)0x00, (byte)0x40, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x7C, (byte)0x00,
(byte)0x93, (byte)0xB8, (byte)0xD5, (byte)0x38, (byte)0x27, (byte)0x48, (byte)0xA6, (byte)0x98, (byte)0xBA, (byte)0x25, (byte)0xF1,
(byte)0xE3, (byte)0x0B, (byte)0xAC, (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05,
(byte)0x20, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x21, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x0B, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x01, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x20,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x21, (byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
};
CompareBinaryForms (binaryForm2, binaryForm1);
}
}
}

View File

@@ -0,0 +1,276 @@
// ObjectSecurityTest.cs - NUnit Test Cases for ObjectSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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); }
}
}
}
}

View File

@@ -0,0 +1,105 @@
// ObjectSecurity_TTest.cs - NUnit Test Cases for ObjectSecurity<T>
//
// Authors:
// James Bellinger (jfb@zer7.com)
#if NET_4_0
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class ObjectSecurity_TTest
{
enum WillWorkRights
{
Value = 1
}
class WillWorkSecurity : ObjectSecurity<WillWorkRights>
{
public WillWorkSecurity ()
: base (false, ResourceType.Unknown)
{
}
}
struct WillFailRights
{
}
class WillFailSecurity : ObjectSecurity<WillFailRights>
{
public WillFailSecurity ()
: base (false, ResourceType.Unknown)
{
}
}
[Test]
public void TypesAreCorrect ()
{
WillWorkSecurity security = new WillWorkSecurity ();
Assert.AreEqual (security.AccessRightType, typeof (WillWorkRights));
Assert.AreEqual (security.AccessRuleType, typeof (AccessRule<WillWorkRights>));
Assert.AreEqual (security.AuditRuleType, typeof (AuditRule<WillWorkRights>));
}
[Test]
public void WillWorkOKUsingAccessFactory ()
{
WillWorkSecurity security = new WillWorkSecurity ();
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
AccessRule<WillWorkRights> rule = (AccessRule<WillWorkRights>)
security.AccessRuleFactory (id, 1, false,
InheritanceFlags.None, PropagationFlags.None,
AccessControlType.Allow);
Assert.AreEqual (rule.AccessControlType, AccessControlType.Allow);
Assert.AreEqual (rule.IdentityReference, id);
Assert.AreEqual (rule.InheritanceFlags, InheritanceFlags.None);
Assert.AreEqual (rule.PropagationFlags, PropagationFlags.None);
Assert.AreEqual (rule.Rights, WillWorkRights.Value);
}
[Test]
public void WillWorkOKUsingConstructor()
{
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
AccessRule<WillWorkRights> rule = new AccessRule<WillWorkRights> (id, WillWorkRights.Value,
AccessControlType.Allow);
Assert.AreEqual (rule.AccessControlType, AccessControlType.Allow);
Assert.AreEqual (rule.IdentityReference, id);
Assert.AreEqual (rule.Rights, WillWorkRights.Value);
}
[Test, ExpectedException (typeof (InvalidCastException))]
public void WillFailFailsUsingFactoryOnGetter()
{
WillFailSecurity security = new WillFailSecurity ();
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
AccessRule<WillFailRights> rule = (AccessRule<WillFailRights>)
security.AccessRuleFactory (id, 1, false,
InheritanceFlags.None, PropagationFlags.None,
AccessControlType.Allow);
WillFailRights rights = rule.Rights;
}
[Test, ExpectedException (typeof (InvalidCastException))]
public void WillFailFailsUsingConstructor()
{
SecurityIdentifier id = new SecurityIdentifier (WellKnownSidType.WorldSid, null);
AccessRule<WillFailRights> rule = new AccessRule<WillFailRights> (id, new WillFailRights(),
AccessControlType.Allow);
}
}
}
#endif

View File

@@ -0,0 +1,48 @@
//
// RawAclTest.cs - NUnit Test Cases for RawAclTest
//
// Author:
// Kenneth Bell
//
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl {
[TestFixture]
public class AclTest {
[Test]
public void GetBinaryForm ()
{
RawAcl acl = new RawAcl (1, 0);
byte[] buffer = new byte[acl.BinaryLength];
acl.GetBinaryForm (buffer, 0);
byte[] sdBinary = new byte[] { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
acl.InsertAce (0, ace);
buffer = new byte[acl.BinaryLength];
acl.GetBinaryForm (buffer, 0);
sdBinary = new byte[] {
0x01, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
}
[Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
public void NonNegativeCapacity ()
{
new RawAcl (GenericAcl.AclRevision, -1);
}
}
}

View File

@@ -0,0 +1,287 @@
//
// RawSecurityDescriptorTest.cs - NUnit Test Cases for RawSecurityDescriptor
//
// Author:
// Kenneth Bell
//
using System;
using System.Security.AccessControl;
using System.Security.Principal;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
namespace MonoTests.System.Security.AccessControl {
[TestFixture]
public class RawSecurityDescriptorTest {
private void CheckSddlConstructor (string sddl, byte[] expectedBinary)
{
RawSecurityDescriptor sd = new RawSecurityDescriptor (sddl);
Assert.That (sd.BinaryLength, Is.GreaterThanOrEqualTo (0));
byte[] buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
Assert.AreEqual (expectedBinary, buffer);
}
private void CheckBinaryConstructor (string expectedSddl, byte[] binary)
{
RawSecurityDescriptor sd = new RawSecurityDescriptor (binary, 0);
Assert.AreEqual (sd.BinaryLength, binary.Length);
Assert.AreEqual (expectedSddl, sd.GetSddlForm (AccessControlSections.All));
}
private void CheckRoundTrip (string sddl)
{
RawSecurityDescriptor sd = new RawSecurityDescriptor (sddl);
byte[] buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
sd = new RawSecurityDescriptor (buffer, 0);
Assert.AreEqual (sddl, sd.GetSddlForm (AccessControlSections.All));
}
[Test]
public void ConstructorEmptyString ()
{
byte[] sdBinary = new byte[] {
0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
CheckSddlConstructor ("", sdBinary);
}
[Test]
public void ConstructorString ()
{
byte[] sdBinary = new byte[] {
0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x14, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x01, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
CheckSddlConstructor ("O:BUG:BAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)", sdBinary);
CheckSddlConstructor ("G:BAO:BUD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)", sdBinary);
CheckSddlConstructor ("G:BAD:(A; ;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)O:BU", sdBinary);
CheckSddlConstructor ("O:buG:baD:(a;;rpwpccdclcswrcwdwoga;;;s-1-0-0)", sdBinary);
sdBinary = new byte[] {
0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00 };
CheckSddlConstructor ("O:BUG:BA", sdBinary);
sdBinary = new byte[] {
0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
0x05, 0x00, 0x38, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x03, 0x00,
0x00, 0x00, 0x53, 0x1A, 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11,
0x98, 0x19, 0x00, 0xAA, 0x00, 0x40, 0x52, 0x9B, 0x53, 0x1A,
0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11, 0x98, 0x19, 0x00, 0xAA,
0x00, 0x40, 0x52, 0x9B, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
CheckSddlConstructor ("O:BUG:BAD:(OA;;RPWPCCDCLCSWRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)", sdBinary);
}
[Test]
public void ConstructorBinary ()
{
byte[] sdBinary = new byte[] {
0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x14, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x01, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
CheckBinaryConstructor ("O:BUG:BAD:(A;;CCDCLCSWRPWPRCWDWOGA;;;S-1-0-0)", sdBinary);
sdBinary = new byte[] {
0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00 };
CheckBinaryConstructor ("O:BUG:BA", sdBinary);
sdBinary = new byte[] {
0x01, 0x00, 0x04, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00,
0x05, 0x00, 0x38, 0x00, 0x3F, 0x00, 0x0E, 0x10, 0x03, 0x00,
0x00, 0x00, 0x53, 0x1A, 0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11,
0x98, 0x19, 0x00, 0xAA, 0x00, 0x40, 0x52, 0x9B, 0x53, 0x1A,
0x72, 0xAB, 0x2F, 0x1E, 0xD0, 0x11, 0x98, 0x19, 0x00, 0xAA,
0x00, 0x40, 0x52, 0x9B, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
CheckBinaryConstructor ("O:BUG:BAD:(OA;;CCDCLCSWRPWPRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)", sdBinary);
}
[Test]
public void FlagMismatch ()
{
// Check setting DACL-present flag on empty SD
RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
Assert.AreEqual (20, sd.BinaryLength);
sd.SetFlags (ControlFlags.DiscretionaryAclPresent);
Assert.AreEqual (20, sd.BinaryLength);
byte[] buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
byte[] sdBinary = new byte[] {
0x01, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
// Check unsetting DACL-present flag on SD with DACL
sd = new RawSecurityDescriptor ("O:BUG:BAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)");
Assert.AreEqual (80, sd.BinaryLength);
sd.SetFlags (sd.ControlFlags & ~ControlFlags.DiscretionaryAclPresent);
Assert.AreEqual (ControlFlags.SelfRelative, sd.ControlFlags);
Assert.AreEqual (52, sd.BinaryLength);
buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
sdBinary = new byte[] {
0x01, 0x00, 0x00, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
}
[Test]
public void GetBinaryForm ()
{
RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
sd.Owner = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
sd.Group = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
sd.DiscretionaryAcl = new RawAcl (1, 0);
sd.SystemAcl = new RawAcl (1, 0);
sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclPresent | ControlFlags.SystemAclPresent);
// Empty ACL form
byte[] buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
byte[] sdBinary = new byte[] {
0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
// Add an ACE to the DACL
SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
sd.DiscretionaryAcl.InsertAce (0, ace);
buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
sdBinary = new byte[] {
0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
// This time with an Object ACE
ObjectAce objectAce = new ObjectAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 0x12345678, builtInAdmins, ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent, new Guid ("189c0dc7-b849-4dea-93a5-6d4cb8857a5c"), new Guid ("53b4a3d4-fe39-468b-bc60-b4fcba772fa5"), false, null);
sd.DiscretionaryAcl = new RawAcl (2, 0);
sd.DiscretionaryAcl.InsertAce (0, objectAce);
buffer = new byte[sd.BinaryLength];
sd.GetBinaryForm (buffer, 0);
sdBinary = new byte[] {
0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00,
0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00,
0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02,
0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x44, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x10,
0x3C, 0x00, 0x78, 0x56, 0x34, 0x12, 0x03, 0x00, 0x00, 0x00,
0xC7, 0x0D, 0x9C, 0x18, 0x49, 0xB8, 0xEA, 0x4D, 0x93, 0xA5,
0x6D, 0x4C, 0xB8, 0x85, 0x7A, 0x5C, 0xD4, 0xA3, 0xB4, 0x53,
0x39, 0xFE, 0x8B, 0x46, 0xBC, 0x60, 0xB4, 0xFC, 0xBA, 0x77,
0x2F, 0xA5, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 };
Assert.AreEqual (sdBinary, buffer);
}
[Test]
public void GetSddlForm ()
{
RawSecurityDescriptor sd = new RawSecurityDescriptor ("");
Assert.AreEqual ("", sd.GetSddlForm (AccessControlSections.All));
// Ask for part of SD that isn't represented
sd.Owner = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
sd.Group = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
Assert.AreEqual ("", sd.GetSddlForm (AccessControlSections.Access));
// Empty ACL form
sd.DiscretionaryAcl = new RawAcl (2, 0);
sd.SystemAcl = new RawAcl (1, 0);
sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclPresent | ControlFlags.SystemAclPresent);
Assert.AreEqual ("O:BUG:BAD:S:", sd.GetSddlForm (AccessControlSections.All));
// Add an ACE to the DACL
SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null);
CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
sd.DiscretionaryAcl.InsertAce (0, ace);
Assert.AreEqual ("O:BUG:BAD:(A;;0x7fffffff;;;BA)S:", sd.GetSddlForm (AccessControlSections.All));
// Add second ACE to the DACL
SecurityIdentifier randomUser = new SecurityIdentifier ("S-1-5-21-324-23423-234-334");
ace = new CommonAce (AceFlags.Inherited | AceFlags.ContainerInherit, AceQualifier.AccessDenied, 0x12345678, randomUser, true, null);
sd.DiscretionaryAcl.InsertAce (0, ace);
Assert.AreEqual ("O:BUD:(XD;CIID;0x12345678;;;S-1-5-21-324-23423-234-334)(A;;0x7fffffff;;;BA)", sd.GetSddlForm (AccessControlSections.Owner | AccessControlSections.Access));
// DACL & SACL flags
sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclProtected | ControlFlags.DiscretionaryAclAutoInherited | ControlFlags.DiscretionaryAclAutoInheritRequired | ControlFlags.SystemAclAutoInherited);
sd.DiscretionaryAcl = new RawAcl (1, 0);
ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null);
sd.DiscretionaryAcl.InsertAce (0, ace);
Assert.AreEqual ("O:BUG:BAD:PARAI(A;;0x7fffffff;;;BA)S:AI", sd.GetSddlForm (AccessControlSections.All));
sd.SetFlags (sd.ControlFlags | ControlFlags.ServerSecurity | ControlFlags.DiscretionaryAclDefaulted);
Assert.AreEqual ("O:BUG:BAD:PARAI(A;;0x7fffffff;;;BA)S:AI", sd.GetSddlForm (AccessControlSections.All));
}
[Test]
public void RoundTrip ()
{
CheckRoundTrip ("O:BUG:BAD:(A;;CCDCLCSWRPWPRCWDWOGA;;;S-1-0-0)");
CheckRoundTrip ("O:BUG:BAD:(A;;KR;;;S-1-0-0)");
CheckRoundTrip ("O:BUG:BAD:(OA;;CCDCLCSWRPWPRCWDWOGA;ab721a53-1e2f-11d0-9819-00aa0040529b;ab721a53-1e2f-11d0-9819-00aa0040529b;S-1-0-0)");
CheckRoundTrip ("O:BUG:BAD:(A;;CCDCLCSWRPRC;;;S-1-0-0)");
CheckRoundTrip ("O:SYG:BAD:(A;;0x12019f;;;SY)(A;;0x12019f;;;BA)");
CheckRoundTrip ("O:SYG:BAD:(A;OICINPIOID;0x12019f;;;SY)");
CheckRoundTrip ("O:SYG:BAS:(AU;SAFA;0x12019f;;;SY)");
}
}
}

View File

@@ -0,0 +1,105 @@
// RegistrySecurityTest.cs - NUnit Test Cases for RegistrySecurity
//
// Authors:
// James Bellinger (jfb@zer7.com)
#if !MOBILE
using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.Win32;
using NUnit.Framework;
namespace MonoTests.System.Security.AccessControl
{
[TestFixture]
public class RegistrySecurityTest
{
[Test]
public void ChangeGroupToEveryone ()
{
string keyName = @"SOFTWARE\Mono RegistrySecurityTest ChangeGroupToEveryone";
RegistrySecurity security;
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
try {
using (RegistryKey key = Registry.CurrentUser.CreateSubKey (keyName)) {
// Before we begin manipulating this, make sure we're in the right spot.
Assert.AreEqual (key.Name, @"HKEY_CURRENT_USER\" + keyName);
// Set the group to Everyone.
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
security = key.GetAccessControl ();
security.SetGroup (worldSid);
key.SetAccessControl (security);
// Make sure it actually became Everyone.
security = key.GetAccessControl ();
Assert.AreEqual (worldSid, security.GetGroup (typeof(SecurityIdentifier)));
}
} finally {
Registry.CurrentUser.DeleteSubKey (keyName);
}
}
[Test]
public void EveryoneCanRead ()
{
string keyName = @"Software\Mono RegistrySecurityTest EveryoneCanRead";
RegistrySecurity security;
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
try {
using (RegistryKey key = Registry.CurrentUser.CreateSubKey (keyName)) {
AuthorizationRuleCollection explicitRules, inheritedRules;
// Before we begin manipulating this, make sure we're in the right spot.
Assert.AreEqual (key.Name, @"HKEY_CURRENT_USER\" + keyName);
// Let's add Everyone to the read list.
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
security = key.GetAccessControl ();
inheritedRules = security.GetAccessRules (false, true, typeof (SecurityIdentifier));
Assert.AreNotEqual (0, inheritedRules.Count);
explicitRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (0, explicitRules.Count);
security.AddAccessRule (new RegistryAccessRule (worldSid,
RegistryRights.FullControl,
AccessControlType.Allow));
key.SetAccessControl (security);
// Verify that we have our permission!
security = key.GetAccessControl ();
inheritedRules = security.GetAccessRules (false, true, typeof (SecurityIdentifier));
Assert.AreNotEqual (0, inheritedRules.Count);
explicitRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (1, explicitRules.Count);
RegistryAccessRule rule = (RegistryAccessRule)explicitRules [0];
Assert.AreEqual (AccessControlType.Allow, rule.AccessControlType);
Assert.AreEqual (worldSid, rule.IdentityReference);
Assert.AreEqual (InheritanceFlags.None, rule.InheritanceFlags);
Assert.AreEqual (PropagationFlags.None, rule.PropagationFlags);
Assert.AreEqual (RegistryRights.FullControl, rule.RegistryRights);
Assert.IsFalse (rule.IsInherited);
}
} finally {
Registry.CurrentUser.DeleteSubKey (keyName);
}
}
}
}
#endif

View File

@@ -0,0 +1,182 @@
// SystemAclTest.cs - NUnit Test Cases for SystemAcl
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// 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 SystemAclTest
{
[Test]
public void StartsEmpty ()
{
Assert.AreEqual (0, new SystemAcl (false, false, 0).Count);
//Assert.AreEqual (0, new SystemAcl (false, false, null).Count);
// ^ MS.NET has a bug here and throws, contrary to their own documentation.
}
[Test]
public void AddAuditMergesFlags ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, false, 0);
sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None);
sacl.AddAudit (AuditFlags.Failure, sid, 1, InheritanceFlags.None, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
CommonAce ace = (CommonAce)sacl [0];
Assert.AreEqual (AuditFlags.Success|AuditFlags.Failure, ace.AuditFlags);
}
[Test]
public void AddAuditCommonAce ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, false, 0);
sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
CommonAce ace = (CommonAce)sacl [0];
Assert.AreEqual (AuditFlags.Success, ace.AuditFlags);
Assert.AreEqual (1, ace.AccessMask);
Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
Assert.IsFalse (ace.IsInherited);
}
[Test]
public void AddAuditCommonAceUsingDSOverload ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, true, 0);
sacl.AddAudit (AuditFlags.Failure, sid, 1, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid ());
Assert.AreEqual (1, sacl.Count);
CommonAce ace = (CommonAce)sacl [0];
Assert.AreEqual (AuditFlags.Failure, ace.AuditFlags);
Assert.AreEqual (1, ace.AccessMask);
Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
Assert.IsFalse (ace.IsInherited);
}
[Test]
public void AddAuditObjectAceAndCommonAce ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, true, 0);
sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.Empty);
sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.None, Guid.Empty, Guid.Empty);
Assert.AreEqual (2, sacl.Count);
CommonAce cace = (CommonAce)sacl [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)sacl [1];
Assert.AreEqual (1, oace.AccessMask);
Assert.AreEqual ("S-1-5-32-544", oace.SecurityIdentifier.Value);
Assert.IsFalse (oace.IsCallback);
Assert.IsFalse (oace.IsInherited);
sacl.AddAudit (AuditFlags.Success, sid, 2, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.None, Guid.Empty, Guid.Empty);
Assert.AreEqual (2, sacl.Count);
CommonAce cace2 = (CommonAce)sacl [0];
Assert.AreEqual (3, cace2.AccessMask);
}
[Test]
public void RemoveSpecific ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, false, 0);
RemoveSpecificBegin (sid, sacl, InheritanceFlags.None);
sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None);
Assert.AreEqual (0, sacl.Count);
}
[Test]
public void RemoveSpecificUsingDSOverload ()
{
SecurityIdentifier sid = new SecurityIdentifier ("BA");
SystemAcl sacl = new SystemAcl (false, true, 0);
RemoveSpecificBegin (sid, sacl, InheritanceFlags.None);
sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty);
Assert.AreEqual (1, sacl.Count);
sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None,
ObjectAceFlags.None, Guid.Empty, Guid.Empty);
Assert.AreEqual (0, sacl.Count);
}
void RemoveSpecificBegin (SecurityIdentifier sid, SystemAcl sacl, InheritanceFlags inheritanceFlags)
{
SecurityIdentifier otherSid = new SecurityIdentifier ("BU");
sacl.AddAudit (AuditFlags.Success, sid, 3, inheritanceFlags, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
sacl.RemoveAuditSpecific (AuditFlags.Failure, sid, 1, inheritanceFlags, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
sacl.RemoveAuditSpecific (AuditFlags.Success, otherSid, 1, inheritanceFlags, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 1, inheritanceFlags, PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
Assert.AreEqual (3, ((CommonAce)sacl [0]).AccessMask);
sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3,
inheritanceFlags ^ InheritanceFlags.ContainerInherit,
PropagationFlags.None);
Assert.AreEqual (1, sacl.Count);
}
[Test]
public void SetAudit ()
{
SecurityIdentifier adminSid = new SecurityIdentifier ("BA"); // S-1-5-32-544
SecurityIdentifier userSid = new SecurityIdentifier ("BU"); // S-1-5-32-545
SystemAcl sacl = new SystemAcl (true, false, 0);
sacl.SetAudit (AuditFlags.Success, adminSid, 1, InheritanceFlags.ObjectInherit, PropagationFlags.None);
sacl.SetAudit (AuditFlags.Success, userSid, 2, InheritanceFlags.None, PropagationFlags.None);
Assert.AreEqual (2, sacl.Count);
CommonAce ace = (CommonAce)sacl [0];
Assert.AreEqual (adminSid, ace.SecurityIdentifier);
Assert.AreEqual (1, ace.AccessMask);
sacl.SetAudit (AuditFlags.Success, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
Assert.AreNotEqual (4, ace.AccessMask);
ace = (CommonAce)sacl [0];
Assert.AreEqual (4, ace.AccessMask);
sacl.SetAudit (AuditFlags.Failure, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
Assert.AreEqual (2, sacl.Count);
ace = (CommonAce)sacl [0];
Assert.AreEqual (AuditFlags.Failure, ace.AuditFlags);
Assert.AreEqual (adminSid, ace.SecurityIdentifier);
ace = (CommonAce)sacl [1];
Assert.AreEqual (AuditFlags.Success, ace.AuditFlags);
Assert.AreEqual (userSid, ace.SecurityIdentifier);
}
}
}