1 // DiscretionaryAclTest.cs - NUnit Test Cases for DiscretionaryAcl
4 // James Bellinger <jfb@zer7.com>
6 // Copyright (C) 2012 James Bellinger
9 using System.Collections.Generic;
10 using System.Security.AccessControl;
11 using System.Security.Principal;
12 using NUnit.Framework;
14 namespace MonoTests.System.Security.AccessControl
17 public class DiscretionaryAclTest
20 public void StartsEmpty ()
22 Assert.AreEqual (0, new DiscretionaryAcl (false, false, 0).Count);
23 Assert.AreEqual (0, new DiscretionaryAcl (false, false, null).Count);
28 public void AddAccessCommonAce ()
30 SecurityIdentifier sid = new SecurityIdentifier ("BA");
31 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
33 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None);
34 Assert.AreEqual (1, dacl.Count);
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);
43 public void AddAccessCommonAceUsingDSOverload ()
45 SecurityIdentifier sid = new SecurityIdentifier ("BA");
46 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
48 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
49 ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid ());
50 Assert.AreEqual (1, dacl.Count);
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);
58 [Test, ExpectedException (typeof (InvalidOperationException))]
59 public void AddAccessObjectAceNonDSFailsEvenIfObjectAceFlagsNoneImplyingCommonAce ()
61 SecurityIdentifier sid = new SecurityIdentifier ("BA");
62 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
64 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None,
65 ObjectAceFlags.None, Guid.Empty, Guid.Empty);
68 [Test, ExpectedException (typeof (InvalidOperationException))]
69 public void AddAccessFailsOnNonCanonical ()
71 SecurityIdentifier sid = new SecurityIdentifier ("BU");
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));
77 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
78 Assert.IsFalse (dacl.IsCanonical);
79 Assert.AreEqual (2, dacl.Count);
81 dacl.AddAccess (AccessControlType.Allow, sid, 1, InheritanceFlags.None, PropagationFlags.None);
84 [Test, ExpectedException (typeof (ArgumentException))]
85 public void InheritanceFlagsRequireContainer ()
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);
92 [Test, ExpectedException (typeof (ArgumentException))]
93 public void PropagationFlagsRequireInheritanceFlagsForAdd ()
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);
101 public void AddAccessObjectAceAndCommonAce ()
103 SecurityIdentifier sid = new SecurityIdentifier ("BA");
104 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
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);
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);
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);
124 dacl.AddAccess (AccessControlType.Allow, sid, 2, InheritanceFlags.None, PropagationFlags.None,
125 ObjectAceFlags.None, Guid.Empty, Guid.Empty);
126 Assert.AreEqual (2, dacl.Count);
128 CommonAce cace2 = (CommonAce)dacl [0];
129 Assert.AreEqual (3, cace2.AccessMask);
132 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
133 public void InvalidAccessControlType ()
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);
144 public void RemoveSpecific ()
146 SecurityIdentifier sid = new SecurityIdentifier ("BA");
147 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
149 RemoveSpecificBegin (sid, dacl, InheritanceFlags.None);
150 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.None, PropagationFlags.None);
151 Assert.AreEqual (0, dacl.Count);
155 public void RemoveSpecificUsingDSOverload ()
157 SecurityIdentifier sid = new SecurityIdentifier ("BA");
158 DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
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);
170 public void RemoveSpecificIsContainer ()
172 SecurityIdentifier sid = new SecurityIdentifier ("BA");
173 DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, 0);
175 RemoveSpecificBegin (sid, dacl, InheritanceFlags.ObjectInherit);
176 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3, InheritanceFlags.ObjectInherit, PropagationFlags.None);
177 Assert.AreEqual (0, dacl.Count);
181 public void RemoveSpecificIgnoresPropagationFlagsWhenMatchingInheritanceFlagsNone()
183 SecurityIdentifier sid = new SecurityIdentifier ("BA");
184 DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
186 RemoveSpecificBegin (sid, dacl, InheritanceFlags.None);
187 dacl.RemoveAccessSpecific (AccessControlType.Allow, sid, 3,
188 InheritanceFlags.None, PropagationFlags.InheritOnly);
189 Assert.AreEqual (0, dacl.Count);
192 void RemoveSpecificBegin (SecurityIdentifier sid, DiscretionaryAcl dacl, InheritanceFlags inheritanceFlags)
194 SecurityIdentifier otherSid = new SecurityIdentifier ("BU");
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);
212 public void PropagationFlagsDoNotRequireInheritanceFlagsForRemoveSpecific ()
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);
221 public void SetAccess ()
223 SecurityIdentifier adminSid = new SecurityIdentifier ("BA"); // S-1-5-32-544
224 SecurityIdentifier userSid = new SecurityIdentifier ("BU"); // S-1-5-32-545
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);
231 CommonAce ace = (CommonAce)dacl [0];
232 Assert.AreEqual (adminSid, ace.SecurityIdentifier);
233 Assert.AreEqual (1, ace.AccessMask);
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);
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);