/// <summary>Canonicalizes the specified Access Control List.</summary>
        /// <param name="acl">The Access Control List.</param>
        public static void Canonicalize(this RawAcl acl)
        {
            if (acl == null)
            {
                throw new ArgumentNullException(nameof(acl));
            }

            // Extract aces to list
            var aces = new System.Collections.Generic.List <GenericAce>(acl.Cast <GenericAce>());

            // Sort aces based on canonical order
            aces.Sort((a, b) => System.Collections.Generic.Comparer <byte> .Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));

            // Add sorted aces back to ACL
            while (acl.Count > 0)
            {
                acl.RemoveAce(0);
            }
            var aceIndex = 0;

            aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
        }
Exemple #2
0
        public static void Constructor3_AdditionalTestCases()
        {
            bool isContainer = false;
            bool isDS        = false;

            RawAcl           rawAcl           = null;
            DiscretionaryAcl discretionaryAcl = null;

            GenericAce gAce     = null;
            byte       revision = 0;
            int        capacity = 0;

            //CustomAce constructor parameters
            AceType  aceType = AceType.AccessAllowed;
            AceFlags aceFlag = AceFlags.None;

            byte[] opaque = null;

            //CompoundAce constructor additional parameters
            int             accessMask      = 0;
            CompoundAceType compoundAceType = CompoundAceType.Impersonation;
            string          sid             = "BG";

            //CommonAce constructor additional parameters
            AceQualifier aceQualifier = 0;

            //ObjectAce constructor additional parameters
            ObjectAceFlags objectAceFlag = 0;
            Guid           objectAceType;
            Guid           inheritedObjectAceType;

            //case 1, an AccessAllowed ACE with a zero access mask is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            gAce     = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0,
                                     new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //drop the Ace from rawAcl
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 2, an inherit-only AccessDenied ACE on an object ACL is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            //15 has all inheritance AceFlags but Inherited
            gAce = new CommonAce((AceFlags)15, AceQualifier.AccessDenied, 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 3, an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            //8 has inheritOnly
            gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 4, 1 CustomAce
            revision = 127;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            aceType  = AceType.MaxDefinedAceType + 1;
            aceFlag  = AceFlags.None;
            opaque   = null;
            gAce     = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));

            //case 5, 1 CompoundAce
            revision = 127;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            // 2 has ContainerInherit
            aceFlag         = (AceFlags)2;
            accessMask      = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce            = new CompoundAce(aceFlag, accessMask, compoundAceType,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)));
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));


            //case 6, 1 ObjectAce
            revision               = 127;
            capacity               = 1;
            rawAcl                 = new RawAcl(revision, capacity);
            aceFlag                = (AceFlags)15; //all inheritance flags ored together but Inherited
            aceQualifier           = AceQualifier.AccessAllowed;
            accessMask             = 1;
            objectAceFlag          = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType          = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag, aceQualifier, accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), objectAceFlag, objectAceType, inheritedObjectAceType, false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = true;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));


            //case 7, no Ace
            revision    = 127;
            capacity    = 1;
            rawAcl      = new RawAcl(revision, capacity);
            isContainer = true;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));


            //case 8, all Aces from case 1, and 3 to 6
            revision = 127;
            capacity = 5;
            sid      = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")).ToString();
            rawAcl   = new RawAcl(revision, capacity);
            //0 access Mask
            gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 1.ToString())), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            //an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed

            gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 2.ToString())), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // ObjectAce
            aceFlag                = (AceFlags)15; //all inheritance flags ored together but Inherited
            aceQualifier           = AceQualifier.AccessAllowed;
            accessMask             = 1;
            objectAceFlag          = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType          = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag, aceQualifier, accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 3.ToString())), objectAceFlag, objectAceType, inheritedObjectAceType, false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // CustomAce
            aceType = AceType.MaxDefinedAceType + 1;
            aceFlag = AceFlags.None;
            opaque  = null;
            gAce    = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // CompoundAce
            aceFlag         = (AceFlags)2;
            accessMask      = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce            = new CompoundAce(aceFlag, accessMask, compoundAceType,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 4.ToString())));
            rawAcl.InsertAce(rawAcl.Count, gAce);

            isContainer = true;
            isDS        = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);

            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));



            discretionaryAcl = null;
            isContainer      = false;
            isDS             = false;
            rawAcl           = null;
            //case 1, rawAcl = null
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl           = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1);
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));



            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl           = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1);
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));
        }
Exemple #3
0
        public static void RemoveAccess_AdditionalTestCases()
        {
            RawAcl           rawAcl           = null;
            DiscretionaryAcl discretionaryAcl = null;
            bool             isContainer      = false;
            bool             isDS             = false;

            int        accessControlType = 0;
            string     sid              = null;
            int        accessMask       = 1;
            int        inheritanceFlags = 0;
            int        propagationFlags = 0;
            GenericAce gAce             = null;
            bool       removePossible   = false;

            byte[] opaque = null;
            //Case 1, remove one ACE from the DiscretionaryAcl with no ACE
            isContainer       = true;
            isDS              = false;
            accessControlType = 1;
            sid              = "BA";
            accessMask       = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            removePossible   = true;
            rawAcl           = new RawAcl(0, 1);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            Assert.True(TestRemoveAccess(discretionaryAcl, rawAcl, (AccessControlType)accessControlType,
                                         new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags, removePossible))
            ;


            //Case 2, remove the last ACE from the DiscretionaryAcl
            isContainer       = true;
            isDS              = false;
            accessControlType = 1;
            sid              = "BA";
            accessMask       = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            removePossible   = true;
            rawAcl           = new RawAcl(0, 1);
            //15 = AceFlags.ObjectInherit |AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly
            gAce = new CommonAce((AceFlags)15, AceQualifier.AccessDenied, accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //remove the ace to create the validation rawAcl
            rawAcl.RemoveAce(rawAcl.Count - 1);
            Assert.True(TestRemoveAccess(discretionaryAcl, rawAcl, (AccessControlType)accessControlType,
                                         new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags, removePossible))
            ;


            //Case 3, accessMask = 0
            Assert.Throws <ArgumentException>(() =>
            {
                isContainer       = true;
                isDS              = false;
                accessControlType = 1;
                sid              = "BA";
                accessMask       = 0;
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl           = new RawAcl(0, 1);
                discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
                discretionaryAcl.RemoveAccess((AccessControlType)accessControlType,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);
            });

            //Case 4, null sid
            Assert.Throws <ArgumentNullException>(() =>
            {
                isContainer       = true;
                isDS              = false;
                accessControlType = 1;
                accessMask        = 1;
                inheritanceFlags  = 3;
                propagationFlags  = 3;
                rawAcl            = new RawAcl(0, 1);
                discretionaryAcl  = new DiscretionaryAcl(isContainer, isDS, rawAcl);
                discretionaryAcl.RemoveAccess((AccessControlType)accessControlType, null, accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);
            });

            //Case 5, all the ACEs in the Dacl are non-qualified ACE, no remove

            isContainer = true;
            isDS        = false;

            inheritanceFlags = 1; //InheritanceFlags.ContainerInherit
            propagationFlags = 2; //PropagationFlags.InheritOnly

            accessControlType = 0;
            sid            = "BA";
            accessMask     = 1;
            removePossible = true;

            rawAcl = new RawAcl(0, 1);
            opaque = new byte[4];
            gAce   = new CustomAce(AceType.MaxDefinedAceType + 1, AceFlags.InheritanceFlags, opaque);;
            rawAcl.InsertAce(0, gAce);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and
            //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException
            Assert.Throws <InvalidOperationException>(() =>
            {
                TestRemoveAccess(discretionaryAcl, rawAcl,
                                 (AccessControlType)accessControlType,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                 accessMask,
                                 (InheritanceFlags)inheritanceFlags,
                                 (PropagationFlags)propagationFlags, removePossible);
            });

            //Case 7, Remove Ace of NOT(AccessControlType.Allow |AccessControlType.Denied) to the DiscretionaryAcl with no ACE,
            // should throw appropriate exception for wrong parameter, bug#287188


            isContainer = true;
            isDS        = false;

            inheritanceFlags = 1; //InheritanceFlags.ContainerInherit
            propagationFlags = 2; //PropagationFlags.InheritOnly

            accessControlType = 100;
            sid        = "BA";
            accessMask = 1;

            rawAcl           = new RawAcl(0, 1);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            Assert.Throws <ArgumentOutOfRangeException>(() =>
            {
                discretionaryAcl.RemoveAccess((AccessControlType)accessControlType,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                              accessMask,
                                              (InheritanceFlags)inheritanceFlags,
                                              (PropagationFlags)propagationFlags);
            });
        }
Exemple #4
0
        public static void AdditionalTestCases()
        {
            RawAcl    rawAcl      = null;
            SystemAcl systemAcl   = null;
            bool      isContainer = false;
            bool      isDS        = false;

            int        auditFlags       = 0;
            string     sid              = null;
            int        accessMask       = 1;
            int        inheritanceFlags = 0;
            int        propagationFlags = 0;
            GenericAce gAce             = null;

            byte[] opaque = null;


            //Case 1, remove one audit ACE from the SystemAcl with no ACE
            isContainer      = true;
            isDS             = false;
            auditFlags       = 1;
            sid              = "BA";
            accessMask       = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            rawAcl           = new RawAcl(0, 1);
            systemAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestRemoveAuditSpecific(systemAcl, rawAcl, (AuditFlags)auditFlags,
                                                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags));


            //Case 2, remove the last one audit ACE from the SystemAcl
            isContainer      = true;
            isDS             = false;
            auditFlags       = 1;
            sid              = "BA";
            accessMask       = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            rawAcl           = new RawAcl(0, 1);
            //79 = AceFlags.SuccessfulAccess | AceFlags.ObjectInherit |AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly
            gAce = new CommonAce((AceFlags)79, AceQualifier.SystemAudit, accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //remove the ace to create the validation rawAcl
            rawAcl.RemoveAce(rawAcl.Count - 1);
            Assert.True(TestRemoveAuditSpecific(systemAcl, rawAcl, (AuditFlags)auditFlags,
                                                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags));

            //Case 3, accessMask = 0

            AssertExtensions.Throws <ArgumentException>("accessMask", () =>
            {
                isContainer      = true;
                isDS             = false;
                auditFlags       = 1;
                sid              = "BA";
                accessMask       = 0;
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl           = new RawAcl(0, 1);
                systemAcl        = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAuditSpecific((AuditFlags)auditFlags,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);
            });

            //Case 4, Audit Qualifier None

            AssertExtensions.Throws <ArgumentException>("auditFlags", () =>
            {
                isContainer      = true;
                isDS             = false;
                auditFlags       = 0;
                sid              = "BA";
                accessMask       = 1;
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl           = new RawAcl(0, 1);
                systemAcl        = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAuditSpecific((AuditFlags)auditFlags,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);
            });
            //Case 5, null sid


            Assert.Throws <ArgumentNullException>(() =>
            {
                isContainer      = true;
                isDS             = false;
                auditFlags       = 1;
                accessMask       = 1;
                sid              = "BA";
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl           = new RawAcl(0, 1);
                systemAcl        = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAuditSpecific((AuditFlags)auditFlags, null, accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);
            });
            //Case 6, all the ACEs in the Sacl are non-qualified ACE, no remove

            Assert.Throws <InvalidOperationException>(() =>
            {
                isContainer      = true;
                isDS             = false;
                inheritanceFlags = 1; //InheritanceFlags.ContainerInherit
                propagationFlags = 2; //PropagationFlags.InheritOnly

                auditFlags = 3;
                sid        = "BA";
                accessMask = 1;
                rawAcl     = new RawAcl(0, 1);
                opaque     = new byte[4];
                gAce       = new CustomAce(AceType.MaxDefinedAceType + 1,
                                           AceFlags.InheritanceFlags | AceFlags.AuditFlags, opaque);
                rawAcl.InsertAce(0, gAce);
                systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
                //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and
                //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException
                TestRemoveAuditSpecific(systemAcl,
                                        rawAcl,
                                        (AuditFlags)auditFlags,
                                        new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                        accessMask,
                                        (InheritanceFlags)inheritanceFlags,
                                        (PropagationFlags)propagationFlags);
            });
        }
        public static void TestRemoveAce(string sddl)
        {
            RawSecurityDescriptor rawSecurityDescriptor = null;
            RawAcl     rawAcl         = null;
            RawAcl     rawAclVerifier = null;
            GenericAce ace            = null;

            rawSecurityDescriptor = new RawSecurityDescriptor(sddl);
            rawAclVerifier        = rawSecurityDescriptor.DiscretionaryAcl;
            rawAcl = Utils.CopyRawACL(rawAclVerifier);
            Assert.True(null != rawAcl && null != rawAclVerifier);
            int index = 0;
            int count = 0;

            //save current count
            count = rawAcl.Count;

            //test remove at -1
            AssertExtensions.Throws <ArgumentOutOfRangeException>(
                "index",
                () =>
            {
                index = -1;
                rawAcl.RemoveAce(index);
            });

            //test remove at value too large
            AssertExtensions.Throws <ArgumentOutOfRangeException>(
                "index",
                () =>
            {
                index = int.MaxValue;
                rawAcl.RemoveAce(index);
            });

            //test remove at 0, only need to catch ArgumentOutOfRangeException if Count = 0
            index = 0;
            try
            {
                //save a copy of the ace
                ace = rawAcl[index];
                rawAcl.RemoveAce(index);
                Assert.False(0 == count);

                //verify the count number decrease one
                Assert.False(rawAcl.Count != count - 1);
                //verify the rawAcl.BinaryLength is updated correctly
                Assert.False(rawAcl.BinaryLength != rawAclVerifier.BinaryLength - ace.BinaryLength);

                //verify the removed ace is equal to the originial ace
                Assert.False(!Utils.IsAceEqual(ace, rawAclVerifier[index]));

                //verify right side aces are equal
                Assert.False(!Utils.AclPartialEqual(rawAcl, rawAclVerifier, index, rawAcl.Count - 1, index + 1, count - 1));
            }
            catch (ArgumentOutOfRangeException)
            {
                Assert.True(0 == count);
                //it is expected, do nothing
            }

            //now insert that ace back
            if (ace != null)
            {
                rawAcl.InsertAce(index, ace);
            }
            //test remove at Count/2, do not need to catch ArgumentOutOfRangeException
            index = count / 2;
            //when count/2 = 0 it is reduandent
            if (0 != index)
            {
                //save a copy of the ace
                ace = rawAcl[index];
                rawAcl.RemoveAce(index);
                //verify the count number decrease one
                Assert.False(rawAcl.Count != count - 1);
                //verify the rawAcl.BinaryLength is updated correctly
                Assert.False(rawAcl.BinaryLength != rawAclVerifier.BinaryLength - ace.BinaryLength);

                //verify the removed ace is equal to the originial ace
                Assert.False(!Utils.IsAceEqual(ace, rawAclVerifier[index]));
                //verify the left and right side aces are equal
                Assert.False(!Utils.AclPartialEqual(rawAcl, rawAclVerifier, 0, index - 1, 0, index - 1) || !Utils.AclPartialEqual(rawAcl, rawAclVerifier, index, rawAcl.Count - 1, index + 1, count - 1));

                //now insert that removed ace
                rawAcl.InsertAce(index, ace);
            }

            //test remove at Count - 1, do not need to catch ArgumentOutOfRangeException
            index = count - 1;
            //when count -1 = -1, 0, or count/2, it is reduandent
            if (-1 != index && 0 != index && count / 2 != index)
            {
                //save a copy of the ace
                ace = rawAcl[index];
                rawAcl.RemoveAce(index);
                //verify the count number decrease one
                Assert.False(rawAcl.Count != count - 1);
                //verify the rawAcl.BinaryLength is updated correctly
                Assert.False(rawAcl.BinaryLength != rawAclVerifier.BinaryLength - ace.BinaryLength);

                //verify the removed ace is equal to the originial ace
                Assert.False(!Utils.IsAceEqual(ace, rawAclVerifier[index]));
                //verify the left and right side aces are equal
                Assert.False(!Utils.AclPartialEqual(rawAcl, rawAclVerifier, 0, index - 1, 0, index - 1) || !Utils.AclPartialEqual(rawAcl, rawAclVerifier, index, rawAcl.Count - 1, index + 1, count - 1));

                //now insert that inserted ace

                rawAcl.InsertAce(index, ace);
            }

            //test remove at Count
            index = count;
            //when count  = 0, or count/2, it is reduandent
            if (0 != index && count / 2 != index)
            {
                Assert.Throws <ArgumentOutOfRangeException>(() =>
                {
                    ace = rawAcl[index];
                    rawAcl.RemoveAce(index);
                });
            }
        }
        public static void RemoveAccessSpecific_AdditionalTestCases()
        {
            RawAcl rawAcl = null;
            DiscretionaryAcl discretionaryAcl = null;
            bool isContainer = false;
            bool isDS = false;

            int accessControlType = 0;
            string sid = null;
            int accessMask = 1;
            int inheritanceFlags = 0;
            int propagationFlags = 0;
            GenericAce gAce = null;
            byte[] opaque = null;
            //Case 1, remove one ACE from the DiscretionaryAcl with no ACE
            isContainer = true;
            isDS = false;
            accessControlType = 1;
            sid = "BA";
            accessMask = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            rawAcl = new RawAcl(0, 1);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            Assert.True(TestRemoveAccessSpecific(discretionaryAcl, rawAcl, (AccessControlType)accessControlType,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags))
            ;


            //Case 2, remove the last one ACE from the DiscretionaryAcl
            isContainer = true;
            isDS = false;
            accessControlType = 0;
            sid = "BA";
            accessMask = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            rawAcl = new RawAcl(0, 1);
            //15 = AceFlags.ObjectInherit |AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly
            gAce = new CommonAce((AceFlags)15, AceQualifier.AccessAllowed, accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //remove the ace to create the validation rawAcl
            rawAcl.RemoveAce(rawAcl.Count - 1);
            Assert.True(TestRemoveAccessSpecific(discretionaryAcl, rawAcl, (AccessControlType)accessControlType,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags))
               ;


            //Case 3, accessMask = 0
            Assert.Throws<ArgumentException>(() =>
            {
                isContainer = true;
                isDS = false;
                accessControlType = 1;
                sid = "BA";
                accessMask = 0;
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl = new RawAcl(0, 1);
                discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
                discretionaryAcl.RemoveAccessSpecific((AccessControlType)accessControlType,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);



            });

            //Case 4, null sid
            Assert.Throws<ArgumentNullException>(() =>
            {
                isContainer = true;
                isDS = false;
                accessControlType = 1;
                accessMask = 1;
                sid = "BA";
                inheritanceFlags = 3;
                propagationFlags = 3;
                rawAcl = new RawAcl(0, 1);
                discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
                discretionaryAcl.RemoveAccessSpecific((AccessControlType)accessControlType, null, accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags);



            });

            //Case 5, all the ACEs in the Dacl are non-qualified ACE, no remove

            isContainer = true;
            isDS = false;

            inheritanceFlags = 1;//InheritanceFlags.ContainerInherit
            propagationFlags = 2; //PropagationFlags.InheritOnly

            accessControlType = 0;
            sid = "BA";
            accessMask = 1;

            rawAcl = new RawAcl(0, 1);
            opaque = new byte[4];
            gAce = new CustomAce(AceType.MaxDefinedAceType + 1, AceFlags.InheritanceFlags, opaque); ;
            rawAcl.InsertAce(0, gAce);
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and
            //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException
            Assert.Throws<InvalidOperationException>(() =>
            {
                TestRemoveAccessSpecific
                        (discretionaryAcl, rawAcl,
                        (AccessControlType)accessControlType,
                        new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                        accessMask,
                        (InheritanceFlags)inheritanceFlags,
                        (PropagationFlags)propagationFlags);

            });

            //Case 7, Remove Specific Ace of NOT(AccessControlType.Allow |AccessControlType.Denied) to the DiscretionaryAcl with no ACE, 
            // should throw appropriate exception for wrong parameter, bug#287188

            Assert.Throws<ArgumentOutOfRangeException>(() =>
            {
                isContainer = true;
                isDS = false;

                inheritanceFlags = 1;//InheritanceFlags.ContainerInherit
                propagationFlags = 2; //PropagationFlags.InheritOnly

                accessControlType = 100;
                sid = "BA";
                accessMask = 1;

                rawAcl = new RawAcl(0, 1);
                discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

                discretionaryAcl.RemoveAccessSpecific((AccessControlType)accessControlType,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                    accessMask,
                    (InheritanceFlags)inheritanceFlags,
                    (PropagationFlags)propagationFlags);


            });
        }
        public static void AdditionalTestCases()
        {
            RawAcl rawAcl = null;
            SystemAcl systemAcl = null;
            bool isContainer = false;
            bool isDS = false;

            int auditFlags = 0;
            string sid = null;
            int accessMask = 1;
            int inheritanceFlags = 0;
            int propagationFlags = 0;
            GenericAce gAce = null;
            bool removePossible = false;
            byte[] opaque = null;

            //Case 1, null sid
            Assert.Throws<ArgumentNullException>(() =>
            {
                isContainer = false;
                isDS = false;
                rawAcl = new RawAcl(0, 1);
                systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAudit(AuditFlags.Success, null, 1, InheritanceFlags.None, PropagationFlags.None);
            });

            //Case 2, SystemAudit Ace but non AuditFlags
            Assert.Throws<ArgumentException>(() =>
            {
                isContainer = false;
                isDS = false;
                rawAcl = new RawAcl(0, 1);
                systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAudit(AuditFlags.None,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")), 1, InheritanceFlags.None, PropagationFlags.None);

            });

            //Case 3, 0 accessMask
            Assert.Throws<ArgumentException>(() =>
            {
                isContainer = false;
                isDS = false;
                rawAcl = new RawAcl(0, 1);
                systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
                systemAcl.RemoveAudit(AuditFlags.Success,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")), 0, InheritanceFlags.None, PropagationFlags.None);

            });

            //Case 4, remove one audit ACE from the SystemAcl with no ACE
            isContainer = true;
            isDS = false;
            auditFlags = 1;
            sid = "BA";
            accessMask = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            removePossible = true;
            rawAcl = new RawAcl(0, 1);
            systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestRemoveAudit(systemAcl, rawAcl, (AuditFlags)auditFlags,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags, removePossible));

            //Case 5, remove the last one ACE from the SystemAcl
            isContainer = true;
            isDS = false;
            auditFlags = 1;
            sid = "BA";
            accessMask = 1;
            inheritanceFlags = 3;
            propagationFlags = 3;
            removePossible = true;
            rawAcl = new RawAcl(0, 1);
            //79 = AceFlags.SuccessfulAccess | AceFlags.ObjectInherit |AceFlags.ContainerInherit | AceFlags.NoPropagateInherit | AceFlags.InheritOnly
            gAce = new CommonAce((AceFlags)79, AceQualifier.SystemAudit, accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //remove the ace to create the validation rawAcl
            rawAcl.RemoveAce(rawAcl.Count - 1);
            Assert.True(TestRemoveAudit(systemAcl, rawAcl, (AuditFlags)auditFlags,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags, removePossible));

            //Case 6, all the ACEs in the Sacl are non-qualified ACE, no remove
            Assert.Throws<InvalidOperationException>(() =>
            {
                isContainer = true;
                isDS = false;
                inheritanceFlags = 1;//InheritanceFlags.ContainerInherit
                propagationFlags = 2; //PropagationFlags.InheritOnly

                auditFlags = 3;
                sid = "BA";
                accessMask = 1;
                rawAcl = new RawAcl(0, 1);
                opaque = new byte[4];
                gAce = new CustomAce(AceType.MaxDefinedAceType + 1, AceFlags.InheritanceFlags | AceFlags.AuditFlags, opaque); ;
                rawAcl.InsertAce(0, gAce);
                systemAcl = new SystemAcl(isContainer, isDS, rawAcl);
                //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and
                //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException
                TestRemoveAudit(systemAcl, rawAcl, (AuditFlags)auditFlags,
    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), accessMask, (InheritanceFlags)inheritanceFlags, (PropagationFlags)propagationFlags, true);
            });
            //Case 7, remove split cause overflow
            // Test case no longer relevant in CoreCLR
            // Non-canonical ACLs cannot be modified
        }
        public static void AdditionalTestCases()
        {
            bool isContainer = false;
            bool isDS        = false;

            RawAcl    rawAcl = null;
            SystemAcl sAcl   = null;

            GenericAce gAce     = null;
            byte       revision = 0;
            int        capacity = 0;
            //CustomAce constructor parameters
            AceType  aceType = AceType.AccessAllowed;
            AceFlags aceFlag = AceFlags.None;

            byte[] opaque = null;
            //CompoundAce constructor additional parameters
            int             accessMask      = 0;
            CompoundAceType compoundAceType = CompoundAceType.Impersonation;
            string          sid             = "BA";
            //CommonAce constructor additional parameters
            AceQualifier aceQualifier = 0;
            //ObjectAce constructor additional parameters
            ObjectAceFlags objectAceFlag = 0;
            Guid           objectAceType;
            Guid           inheritedObjectAceType;

            //case 1, an SystemAudit ACE with a zero access mask is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            gAce     = new CommonAce(AceFlags.AuditFlags,
                                     AceQualifier.SystemAudit,
                                     0,
                                     new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                     false,
                                     null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            //drop the ace from the rawAcl
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));


            //case 2, an inherit-only SystemAudit ACE on an object ACL is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            gAce     = new CommonAce(AceFlags.InheritanceFlags | AceFlags.AuditFlags,
                                     AceQualifier.SystemAudit,
                                     1,
                                     new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                     false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            rawAcl.RemoveAce(0);

            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 3, an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            //200 has inheritOnly, SuccessfulAccess and FailedAccess
            gAce = new CommonAce((AceFlags)200,
                                 AceQualifier.SystemAudit,
                                 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                 false,
                                 null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 4, a SystemAudit ACE without Success or Failure Flags is meaningless, will be removed
            revision = 255;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            gAce     = new CommonAce(AceFlags.None,
                                     AceQualifier.SystemAudit,
                                     1,
                                     new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                     false,
                                     null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //audit ACE does not specify either Success or Failure Flags is removed
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 5, a CustomAce
            revision = 127;
            capacity = 1;
            rawAcl   = new RawAcl(revision, capacity);
            aceType  = AceType.MaxDefinedAceType + 1;
            aceFlag  = AceFlags.AuditFlags;
            opaque   = null;
            gAce     = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));

            //case 6, a CompoundAce
            revision        = 127;
            capacity        = 1;
            rawAcl          = new RawAcl(revision, capacity);
            aceFlag         = AceFlags.AuditFlags;
            accessMask      = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce            = new CompoundAce(aceFlag,
                                              accessMask,
                                              compoundAceType,
                                              new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)));
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));

            //case 7, a ObjectAce
            revision               = 127;
            capacity               = 1;
            rawAcl                 = new RawAcl(revision, capacity);
            aceFlag                = AceFlags.InheritanceFlags | AceFlags.AuditFlags;
            aceQualifier           = AceQualifier.SystemAudit;
            accessMask             = 1;
            objectAceFlag          = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType          = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag,
                                 aceQualifier,
                                 accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                                 objectAceFlag, objectAceType,
                                 inheritedObjectAceType,
                                 false,
                                 null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS        = true;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 8, no Ace
            revision    = 127;
            capacity    = 1;
            rawAcl      = new RawAcl(revision, capacity);
            isContainer = true;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 9, Aces from case 1 to 7
            revision = 127;
            capacity = 5;
            sid      = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)).ToString();
            rawAcl   = new RawAcl(revision, capacity);
            //an SystemAudit ACE with a zero access mask
            //is meaningless, will be removed
            gAce = new CommonAce(AceFlags.AuditFlags,
                                 AceQualifier.SystemAudit,
                                 0,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 1.ToString()),
                                 false,
                                 null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object
            //is meaningless, will be removed
            //200 has inheritOnly, SuccessfulAccess and FailedAccess
            gAce = new CommonAce((AceFlags)200,
                                 AceQualifier.SystemAudit,
                                 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 2.ToString()),
                                 false,
                                 null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a SystemAudit ACE without Success or Failure Flags
            //is meaningless, will be removed
            gAce = new CommonAce(AceFlags.None,
                                 AceQualifier.SystemAudit,
                                 1,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 3.ToString()),
                                 false,
                                 null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a ObjectAce
            aceFlag                = AceFlags.InheritanceFlags | AceFlags.AuditFlags;
            aceQualifier           = AceQualifier.SystemAudit;
            accessMask             = 1;
            objectAceFlag          = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType          = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag,
                                 aceQualifier,
                                 accessMask,
                                 new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 4.ToString()),
                                 objectAceFlag, objectAceType,
                                 inheritedObjectAceType,
                                 false,
                                 null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            // a CustomAce
            gAce = new CustomAce(AceType.MaxDefinedAceType + 1,
                                 AceFlags.AuditFlags,
                                 null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a CompoundAce
            gAce = new CompoundAce(AceFlags.AuditFlags,
                                   1,
                                   CompoundAceType.Impersonation,
                                   new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 5.ToString()));
            rawAcl.InsertAce(rawAcl.Count, gAce);

            isContainer = true;
            isDS        = false;
            sAcl        = new SystemAcl(isContainer, isDS, rawAcl);
            //the first 3 Aces will be removed by SystemAcl constructor
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));
        }
        public static void Constructor3_AdditionalTestCases()
        {
            bool isContainer = false;
            bool isDS = false;

            RawAcl rawAcl = null;
            DiscretionaryAcl discretionaryAcl = null;

            GenericAce gAce = null;
            byte revision = 0;
            int capacity = 0;

            //CustomAce constructor parameters
            AceType aceType = AceType.AccessAllowed;
            AceFlags aceFlag = AceFlags.None;
            byte[] opaque = null;

            //CompoundAce constructor additional parameters
            int accessMask = 0;
            CompoundAceType compoundAceType = CompoundAceType.Impersonation;
            string sid = "BG";

            //CommonAce constructor additional parameters
            AceQualifier aceQualifier = 0;

            //ObjectAce constructor additional parameters
            ObjectAceFlags objectAceFlag = 0;
            Guid objectAceType;
            Guid inheritedObjectAceType;

            //case 1, an AccessAllowed ACE with a zero access mask is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //drop the Ace from rawAcl
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 2, an inherit-only AccessDenied ACE on an object ACL is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            //15 has all inheritance AceFlags but Inherited
            gAce = new CommonAce((AceFlags)15, AceQualifier.AccessDenied, 1,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 3, an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            //8 has inheritOnly
            gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);

            //the only ACE is a meaningless ACE, will be removed
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));

            //case 4, 1 CustomAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            aceType = AceType.MaxDefinedAceType + 1;
            aceFlag = AceFlags.None;
            opaque = null;
            gAce = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));

            //case 5, 1 CompoundAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            // 2 has ContainerInherit
            aceFlag = (AceFlags)2;
            accessMask = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce = new CompoundAce(aceFlag, accessMask, compoundAceType,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)));
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));


            //case 6, 1 ObjectAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            aceFlag = (AceFlags)15; //all inheritance flags ored together but Inherited
            aceQualifier = AceQualifier.AccessAllowed;
            accessMask = 1;
            objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag, aceQualifier, accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), objectAceFlag, objectAceType, inheritedObjectAceType, false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = true;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));


            //case 7, no Ace
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            isContainer = true;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));


            //case 8, all Aces from case 1, and 3 to 6 
            revision = 127;
            capacity = 5;
            sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")).ToString();
            rawAcl = new RawAcl(revision, capacity);
            //0 access Mask
            gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 1.ToString())), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            //an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed

            gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1,
            new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 2.ToString())), false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // ObjectAce
            aceFlag = (AceFlags)15; //all inheritance flags ored together but Inherited
            aceQualifier = AceQualifier.AccessAllowed;
            accessMask = 1;
            objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag, aceQualifier, accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 3.ToString())), objectAceFlag, objectAceType, inheritedObjectAceType, false, null);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // CustomAce
            aceType = AceType.MaxDefinedAceType + 1;
            aceFlag = AceFlags.None;
            opaque = null;
            gAce = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(rawAcl.Count, gAce);

            // CompoundAce					
            aceFlag = (AceFlags)2;
            accessMask = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce = new CompoundAce(aceFlag, accessMask, compoundAceType,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 4.ToString())));
            rawAcl.InsertAce(rawAcl.Count, gAce);

            isContainer = true;
            isDS = false;

            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);

            //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical

            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl));



            discretionaryAcl = null;
            isContainer = false;
            isDS = false;
            rawAcl = null;
            //case 1, rawAcl = null
            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1);
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));



            discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl);
            rawAcl = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1);
            Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl));


        }
        public static void AdditionalTestCases()
        {

            bool isContainer = false;
            bool isDS = false;

            RawAcl rawAcl = null;
            SystemAcl sAcl = null;

            GenericAce gAce = null;
            byte revision = 0;
            int capacity = 0;
            //CustomAce constructor parameters
            AceType aceType = AceType.AccessAllowed;
            AceFlags aceFlag = AceFlags.None;
            byte[] opaque = null;
            //CompoundAce constructor additional parameters
            int accessMask = 0;
            CompoundAceType compoundAceType = CompoundAceType.Impersonation;
            string sid = "BA";
            //CommonAce constructor additional parameters
            AceQualifier aceQualifier = 0;
            //ObjectAce constructor additional parameters
            ObjectAceFlags objectAceFlag = 0;
            Guid objectAceType;
            Guid inheritedObjectAceType;
            //case 1, an SystemAudit ACE with a zero access mask is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            gAce = new CommonAce(AceFlags.AuditFlags,
                    AceQualifier.SystemAudit,
                    0,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                    false,
                    null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            //drop the ace from the rawAcl
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));


            //case 2, an inherit-only SystemAudit ACE on an object ACL is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            gAce = new CommonAce(AceFlags.InheritanceFlags | AceFlags.AuditFlags,
                    AceQualifier.SystemAudit,
                    1,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                    false, null);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            rawAcl.RemoveAce(0);

            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 3, an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed
            revision = 0;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            //200 has inheritOnly, SuccessfulAccess and FailedAccess
            gAce = new CommonAce((AceFlags)200,
                    AceQualifier.SystemAudit,
                    1,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                    false,
                    null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //the only ACE is a meaningless ACE, will be removed
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 4, a SystemAudit ACE without Success or Failure Flags is meaningless, will be removed
            revision = 255;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            gAce = new CommonAce(AceFlags.None,
        AceQualifier.SystemAudit,
        1,
        new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
        false,
        null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //audit ACE does not specify either Success or Failure Flags is removed
            rawAcl.RemoveAce(0);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 5, a CustomAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            aceType = AceType.MaxDefinedAceType + 1;
            aceFlag = AceFlags.AuditFlags;
            opaque = null;
            gAce = new CustomAce(aceType, aceFlag, opaque);
            rawAcl.InsertAce(0, gAce);
            isContainer = false;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));

            //case 6, a CompoundAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            aceFlag = AceFlags.AuditFlags;
            accessMask = 1;
            compoundAceType = CompoundAceType.Impersonation;
            gAce = new CompoundAce(aceFlag,
                accessMask,
                compoundAceType,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)));
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));

            //case 7, a ObjectAce
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            aceFlag = AceFlags.InheritanceFlags | AceFlags.AuditFlags;
            aceQualifier = AceQualifier.SystemAudit;
            accessMask = 1;
            objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag,
                aceQualifier,
                accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)),
                objectAceFlag, objectAceType,
                inheritedObjectAceType,
                false,
                null);
            rawAcl.InsertAce(0, gAce);
            isContainer = true;
            isDS = true;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 8, no Ace
            revision = 127;
            capacity = 1;
            rawAcl = new RawAcl(revision, capacity);
            isContainer = true;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl));

            //case 9, Aces from case 1 to 7 
            revision = 127;
            capacity = 5;
            sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)).ToString();
            rawAcl = new RawAcl(revision, capacity);
            //an SystemAudit ACE with a zero access mask
            //is meaningless, will be removed                    
            gAce = new CommonAce(AceFlags.AuditFlags,
                    AceQualifier.SystemAudit,
                    0,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 1.ToString()),
                    false,
                    null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object
            //is meaningless, will be removed
            //200 has inheritOnly, SuccessfulAccess and FailedAccess
            gAce = new CommonAce((AceFlags)200,
                    AceQualifier.SystemAudit,
                    1,
                    new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 2.ToString()),
                    false,
                    null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a SystemAudit ACE without Success or Failure Flags
            //is meaningless, will be removed                    
            gAce = new CommonAce(AceFlags.None,
        AceQualifier.SystemAudit,
        1,
        new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 3.ToString()),
        false,
        null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a ObjectAce
            aceFlag = AceFlags.InheritanceFlags | AceFlags.AuditFlags;
            aceQualifier = AceQualifier.SystemAudit;
            accessMask = 1;
            objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent;
            objectAceType = new Guid("11111111-1111-1111-1111-111111111111");
            inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222");
            gAce = new ObjectAce(aceFlag,
                aceQualifier,
                accessMask,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 4.ToString()),
                objectAceFlag, objectAceType,
                inheritedObjectAceType,
                false,
                null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            // a CustomAce
            gAce = new CustomAce(AceType.MaxDefinedAceType + 1,
                AceFlags.AuditFlags,
                null);
            rawAcl.InsertAce(rawAcl.Count, gAce);
            //a CompoundAce
            gAce = new CompoundAce(AceFlags.AuditFlags,
                1,
                CompoundAceType.Impersonation,
                new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 5.ToString()));
            rawAcl.InsertAce(rawAcl.Count, gAce);

            isContainer = true;
            isDS = false;
            sAcl = new SystemAcl(isContainer, isDS, rawAcl);
            //the first 3 Aces will be removed by SystemAcl constructor
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);
            rawAcl.RemoveAce(0);
            //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical
            Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl));

        }