Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / corlib / Test / System.Security.AccessControl / DiscretionaryAclTest.cs
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]
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]
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]
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))]
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))]
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))]
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))]
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]
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))]
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]
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]
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]
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]
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
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]
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]
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