1 // DiscretionaryAclTest.cs - NUnit Test Cases for DiscretionaryAcl 2 // 3 // Authors: 4 // James Bellinger <jfb@zer7.com> 5 // 6 // Copyright (C) 2012 James Bellinger 7 8 using System; 9 using System.Collections.Generic; 10 using System.Security.AccessControl; 11 using System.Security.Principal; 12 using NUnit.Framework; 13 14 namespace MonoTests.System.Security.AccessControl 15 { 16 [TestFixture] 17 public class DiscretionaryAclTest 18 { 19 [Test] StartsEmpty()20 public void StartsEmpty () 21 { 22 Assert.AreEqual (0, new DiscretionaryAcl (false, false, 0).Count); 23 Assert.AreEqual (0, new DiscretionaryAcl (false, false, null).Count); 24 25 } 26 27 [Test] AddAccessCommonAce()28 public void AddAccessCommonAce () 29 { 30 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 31 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 32 33 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None); 34 Assert.AreEqual (1, dacl.Count); 35 36 CommonAce ace = (CommonAce)dacl[0]; 37 Assert.AreEqual (1, ace.AccessMask); 38 Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value); 39 Assert.IsFalse (ace.IsInherited); 40 } 41 42 [Test] AddAccessCommonAceUsingDSOverload()43 public void AddAccessCommonAceUsingDSOverload () 44 { 45 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 46 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0); 47 48 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None, 49 ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid ()); 50 Assert.AreEqual (1, dacl.Count); 51 52 CommonAce ace = (CommonAce)dacl [0]; 53 Assert.AreEqual (1, ace.AccessMask); 54 Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value); 55 Assert.IsFalse (ace.IsInherited); 56 } 57 58 [Test, ExpectedException (typeof (InvalidOperationException))] AddAccessObjectAceNonDSFailsEvenIfObjectAceFlagsNoneImplyingCommonAce()59 public void AddAccessObjectAceNonDSFailsEvenIfObjectAceFlagsNoneImplyingCommonAce () 60 { 61 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 62 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 63 64 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None, 65 ObjectAceFlags.None, Guid.Empty, Guid.Empty); 66 } 67 68 [Test, ExpectedException (typeof (InvalidOperationException))] AddAccessFailsOnNonCanonical()69 public void AddAccessFailsOnNonCanonical () 70 { 71 SecurityIdentifier sid = new SecurityIdentifier ("BU"); 72 73 RawAcl acl = new RawAcl (RawAcl.AclRevision, 0); 74 acl.InsertAce (0, new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null)); 75 acl.InsertAce (1, new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null)); 76 77 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl); 78 Assert.IsFalse (dacl.IsCanonical); 79 Assert.AreEqual (2, dacl.Count); 80 81 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None); 82 } 83 84 [Test, ExpectedException (typeof (ArgumentException))] InheritanceFlagsRequireContainer()85 public void InheritanceFlagsRequireContainer () 86 { 87 SecurityIdentifier sid = new SecurityIdentifier ("BU"); 88 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 89 dacl.AddAccess (AccessControlType.Allow, sid, 3, InheritanceFlags.ContainerInherit, PropagationFlags.None); 90 } 91 92 [Test, ExpectedException (typeof (ArgumentException))] PropagationFlagsRequireInheritanceFlagsForAdd()93 public void PropagationFlagsRequireInheritanceFlagsForAdd () 94 { 95 SecurityIdentifier sid = new SecurityIdentifier ("BU"); 96 DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0); 97 dacl.AddAccess (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.InheritOnly); 98 } 99 100 [Test] AddAccessObjectAceAndCommonAce()101 public void AddAccessObjectAceAndCommonAce () 102 { 103 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 104 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0); 105 106 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None, 107 ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.Empty); 108 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None, 109 ObjectAceFlags.None, Guid.Empty, Guid.Empty); 110 Assert.AreEqual (2, dacl.Count); 111 112 CommonAce cace = (CommonAce)dacl [0]; 113 Assert.AreEqual (1, cace.AccessMask); 114 Assert.AreEqual ("S-1-5-32-544", cace.SecurityIdentifier.Value); 115 Assert.IsFalse (cace.IsCallback); 116 Assert.IsFalse (cace.IsInherited); 117 118 ObjectAce oace = (ObjectAce)dacl [1]; 119 Assert.AreEqual (1, oace.AccessMask); 120 Assert.AreEqual ("S-1-5-32-544", oace.SecurityIdentifier.Value); 121 Assert.IsFalse (oace.IsCallback); 122 Assert.IsFalse (oace.IsInherited); 123 124 dacl.AddAccess (AccessControlType.Allow, sid, 2, InheritanceFlags.None, PropagationFlags.None, 125 ObjectAceFlags.None, Guid.Empty, Guid.Empty); 126 Assert.AreEqual (2, dacl.Count); 127 128 CommonAce cace2 = (CommonAce)dacl [0]; 129 Assert.AreEqual (3, cace2.AccessMask); 130 } 131 132 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))] InvalidAccessControlType()133 public void InvalidAccessControlType () 134 { 135 // This is also testing the fact that the AccessControlType is checked before the 136 // InheritanceFlags are validated -- IsContainer is false here, so if the InheritanceFlags 137 // were checked first, ArgumentException would be thrown instead. 138 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 139 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 140 dacl.AddAccess ((AccessControlType)43210, sid, 1, InheritanceFlags.ContainerInherit, PropagationFlags.None); 141 } 142 143 [Test] RemoveSpecific()144 public void RemoveSpecific () 145 { 146 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 147 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 148 149 RemoveSpecificBegin (sid, dacl, InheritanceFlags.None); 150 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None); 151 Assert.AreEqual (0, dacl.Count); 152 } 153 154 [Test] RemoveSpecificUsingDSOverload()155 public void RemoveSpecificUsingDSOverload () 156 { 157 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 158 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0); 159 160 RemoveSpecificBegin (sid, dacl, InheritanceFlags.None); 161 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None, 162 ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty); 163 Assert.AreEqual (1, dacl.Count); 164 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None, 165 ObjectAceFlags.None, Guid.Empty, Guid.Empty); 166 Assert.AreEqual (0, dacl.Count); 167 } 168 169 [Test] RemoveSpecificIsContainer()170 public void RemoveSpecificIsContainer () 171 { 172 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 173 DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0); 174 175 RemoveSpecificBegin (sid, dacl, InheritanceFlags.ObjectInherit); 176 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.ObjectInherit, PropagationFlags.None); 177 Assert.AreEqual (0, dacl.Count); 178 } 179 180 [Test] RemoveSpecificIgnoresPropagationFlagsWhenMatchingInheritanceFlagsNone()181 public void RemoveSpecificIgnoresPropagationFlagsWhenMatchingInheritanceFlagsNone() 182 { 183 SecurityIdentifier sid = new SecurityIdentifier ("BA"); 184 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 185 186 RemoveSpecificBegin (sid, dacl, InheritanceFlags.None); 187 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, 188 InheritanceFlags.None, PropagationFlags.InheritOnly); 189 Assert.AreEqual (0, dacl.Count); 190 } 191 RemoveSpecificBegin(SecurityIdentifier sid, DiscretionaryAcl dacl, InheritanceFlags inheritanceFlags)192 void RemoveSpecificBegin (SecurityIdentifier sid, DiscretionaryAcl dacl, InheritanceFlags inheritanceFlags) 193 { 194 SecurityIdentifier otherSid = new SecurityIdentifier ("BU"); 195 196 dacl.AddAccess (AccessControlType.Allow, sid, 3, inheritanceFlags, PropagationFlags.None); 197 Assert.AreEqual (1, dacl.Count); 198 dacl.RemoveAccessSpecific (AccessControlType.Deny, sid, 1, inheritanceFlags, PropagationFlags.None); 199 Assert.AreEqual (1, dacl.Count); 200 dacl.RemoveAccessSpecific (AccessControlType.Allow, otherSid, 1, inheritanceFlags, PropagationFlags.None); 201 Assert.AreEqual (1, dacl.Count); 202 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 1, inheritanceFlags, PropagationFlags.None); 203 Assert.AreEqual (1, dacl.Count); 204 Assert.AreEqual (3, ((CommonAce)dacl [0]).AccessMask); 205 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, 206 inheritanceFlags ^ InheritanceFlags.ContainerInherit, 207 PropagationFlags.None); 208 Assert.AreEqual (1, dacl.Count); 209 } 210 211 [Test] PropagationFlagsDoNotRequireInheritanceFlagsForRemoveSpecific()212 public void PropagationFlagsDoNotRequireInheritanceFlagsForRemoveSpecific () 213 { 214 SecurityIdentifier sid = new SecurityIdentifier ("BU"); 215 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0); 216 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, 217 InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly); 218 } 219 220 [Test] SetAccess()221 public void SetAccess () 222 { 223 SecurityIdentifier adminSid = new SecurityIdentifier ("BA"); // S-1-5-32-544 224 SecurityIdentifier userSid = new SecurityIdentifier ("BU"); // S-1-5-32-545 225 226 DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0); 227 dacl.SetAccess (AccessControlType.Allow, adminSid, 1, InheritanceFlags.ObjectInherit, PropagationFlags.None); 228 dacl.SetAccess (AccessControlType.Allow, userSid, 2, InheritanceFlags.None, PropagationFlags.None); 229 Assert.AreEqual (2, dacl.Count); 230 231 CommonAce ace = (CommonAce)dacl [0]; 232 Assert.AreEqual (adminSid, ace.SecurityIdentifier); 233 Assert.AreEqual (1, ace.AccessMask); 234 235 dacl.SetAccess (AccessControlType.Allow, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None); 236 Assert.AreNotEqual (4, ace.AccessMask); // remove and add, not modify, despite AccessMask having a setter 237 ace = (CommonAce)dacl [0]; 238 Assert.AreEqual (4, ace.AccessMask); 239 240 dacl.SetAccess (AccessControlType.Deny, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None); 241 Assert.AreEqual (3, dacl.Count); 242 ace = (CommonAce)dacl [0]; 243 Assert.AreEqual (AceQualifier.AccessDenied, ace.AceQualifier); 244 ace = (CommonAce)dacl [1]; 245 Assert.AreEqual (AceQualifier.AccessAllowed, ace.AceQualifier); 246 } 247 } 248 } 249 250