1 // CommonAclTest.cs - NUnit Test Cases for CommonAcl
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 CommonAclTest
18 	{
19 		[Test]
RevisionOK()20 		public void RevisionOK ()
21 		{
22 			DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 0);
23 			Assert.AreEqual (2, dacl.Revision);
24 		}
25 
26 		[Test]
RevisionDSOK()27 		public void RevisionDSOK ()
28 		{
29 			DiscretionaryAcl dacl = new DiscretionaryAcl(false, true, 0);
30 			Assert.AreEqual (4, dacl.Revision);
31 		}
32 
33 		[Test]
NullRawAclRevisionOK()34 		public void NullRawAclRevisionOK ()
35 		{
36 			DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, null);
37 			Assert.AreEqual (2, dacl1.Revision);
38 
39 			DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, true, null);
40 			Assert.AreEqual (4, dacl2.Revision);
41 		}
42 
43 		[Test]
UsesRawAclRevision()44 		public void UsesRawAclRevision ()
45 		{
46 			RawAcl acl1 = new RawAcl (RawAcl.AclRevisionDS, 0);
47 			DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl1);
48 			Assert.AreEqual (4, dacl1.Revision);
49 
50 			RawAcl acl2 = new RawAcl (RawAcl.AclRevision, 0);
51 			DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, true, acl2);
52 			Assert.AreEqual (2, dacl2.Revision);
53 		}
54 
55 		[Test]
IndexerMakesCopies()56 		public void IndexerMakesCopies ()
57 		{
58 			// This behavior is mentioned in the DiscretionaryAcl RawAcl constructor overload.
59 			// Turns out it applies to more than just the constructor.
60 			SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
61 
62 			// RawAcl does not make copies.
63 			RawAcl acl = new RawAcl (RawAcl.AclRevision, 1);
64 			CommonAce ace = new CommonAce (AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 1, worldSid, false, null);
65 			acl.InsertAce (0, ace);
66 			Assert.AreSame (acl [0], acl [0]);
67 
68 			// CommonAcl does.
69 			SystemAcl sacl = new SystemAcl (false, false, acl);
70 			Assert.AreNotSame (sacl [0], sacl [0]);
71 
72 			// Make sure the copying occurs in the constructor as well as the indexer.
73 			ace.AceFlags = AceFlags.FailedAccess;
74 			Assert.AreEqual (AceFlags.SuccessfulAccess, sacl [0].AceFlags);
75 		}
76 
77 		[Test]
EmptyBinaryLengthOK()78 		public void EmptyBinaryLengthOK()
79 		{
80 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, 0);
81 			Assert.AreEqual (8, dacl.BinaryLength);
82 		}
83 
84 		[Test]
EmptyBinaryFormOK()85 		public void EmptyBinaryFormOK()
86 		{
87 			DiscretionaryAcl dacl = new DiscretionaryAcl(false, false, 0);
88 			byte[] buffer = new byte[8];
89 			dacl.GetBinaryForm (buffer, 0);
90 
91 			Assert.AreEqual (2, buffer [0]); // Revision
92 			Assert.AreEqual (8, ToUInt16 (buffer, 2)); // ACL Size
93 			Assert.AreEqual (0, ToUInt16 (buffer, 4)); // ACE Count
94 		}
95 
96 		[Test]
EmptyBinaryFormDSOK()97 		public void EmptyBinaryFormDSOK()
98 		{
99 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, true, 0);
100 			byte[] buffer = new byte[8];
101 			dacl.GetBinaryForm (buffer, 0);
102 
103 			Assert.AreEqual (4, buffer [0]); // Revision
104 			Assert.AreEqual (8, ToUInt16 (buffer, 2)); // ACL Size
105 			Assert.AreEqual (0, ToUInt16 (buffer, 4)); // ACE Count
106 		}
107 
108 		[Test] // ... stumbled upon this by choosing Guid.Empty when needing an arbitrary GUID ...
GuidEmptyMergesRegardlessOfFlagsAndOpaqueDataIsNotConsidered()109 		public void GuidEmptyMergesRegardlessOfFlagsAndOpaqueDataIsNotConsidered ()
110 		{
111 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
112 
113 			RawAcl acl = MakeRawAcl (new GenericAce[] {
114 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, true, new byte[12]),
115 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid, false, new byte[8]), // gets merged
116 				new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid,
117 				               ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty, false, new byte[8]),
118 				new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid,
119 				               ObjectAceFlags.InheritedObjectAceTypePresent, Guid.Empty, Guid.Empty, true, new byte[16]), // gets merged
120 				new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 4, sid,
121 				               ObjectAceFlags.InheritedObjectAceTypePresent, Guid.Empty, Guid.NewGuid (), true, new byte[4])
122 			});
123 			Assert.AreEqual (236, acl.BinaryLength);
124 
125 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
126 			Assert.IsTrue (dacl.IsCanonical);
127 			Assert.AreEqual (3, dacl.Count);
128 
129 			CommonAce cace = (CommonAce)dacl [0];
130 			Assert.AreEqual (12, cace.OpaqueLength);
131 			Assert.AreEqual (5, cace.AccessMask);
132 			Assert.IsTrue (cace.IsCallback);
133 
134 			ObjectAce oace = (ObjectAce)dacl [1];
135 			Assert.AreEqual (8, oace.OpaqueLength);
136 			Assert.AreEqual (3, oace.AccessMask);
137 			Assert.AreEqual (ObjectAceFlags.ObjectAceTypePresent, oace.ObjectAceFlags);
138 			Assert.AreEqual (Guid.Empty, oace.ObjectAceType);
139 			Assert.IsFalse (oace.IsCallback);
140 		}
141 
142 		[Test]
DetectsCanonicalMergesAndRemovesInheritedAces()143 		public void DetectsCanonicalMergesAndRemovesInheritedAces ()
144 		{
145 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
146 
147 			RawAcl acl = MakeRawAcl(new GenericAce[] {
148 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
149 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null),
150 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
151 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null),
152 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
153 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null)
154 			});
155 			Assert.AreEqual (6, acl.Count);
156 
157 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
158 			Assert.IsTrue (dacl.IsCanonical);
159 			Assert.AreEqual (4, dacl.Count);
160 
161 			Assert.AreEqual (AceFlags.None, ((CommonAce)dacl [0]).AceFlags);
162 			Assert.AreEqual (AceFlags.None, ((CommonAce)dacl [1]).AceFlags);
163 			Assert.AreEqual (AceFlags.Inherited, ((CommonAce)dacl [2]).AceFlags);
164 			Assert.AreEqual (AceFlags.Inherited, ((CommonAce)dacl [3]).AceFlags);
165 			Assert.AreEqual (AceQualifier.AccessDenied, ((CommonAce)dacl [0]).AceQualifier);
166 			Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [1]).AceQualifier);
167 			Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [2]).AceQualifier);
168 			Assert.AreEqual (AceQualifier.AccessAllowed, ((CommonAce)dacl [3]).AceQualifier);
169 			GenericAce ace7 = dacl[0];
170 			Assert.IsInstanceOfType (typeof (CommonAce), ace7);
171 
172 			dacl.RemoveInheritedAces ();
173 			Assert.AreEqual (2, dacl.Count);
174 
175 			dacl.Purge (sid);
176 			Assert.AreEqual (0, dacl.Count);
177 		}
178 
179 		[Test]
MergesAfterSortingForMultipleSids()180 		public void MergesAfterSortingForMultipleSids ()
181 		{
182 			SecurityIdentifier adminSid = new SecurityIdentifier
183 				(WellKnownSidType.BuiltinAdministratorsSid, null); // S-1-5-32-544
184 
185 			SecurityIdentifier userSid = new SecurityIdentifier
186 				(WellKnownSidType.BuiltinUsersSid, null); // S-1-5-32-545
187 
188 			RawAcl acl = MakeRawAcl(new GenericAce[] {
189 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, userSid, false, null),
190 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 2, adminSid, false, null),
191 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, userSid, false, null),
192 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, adminSid, false, null),
193 			});
194 
195 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
196 			Assert.IsTrue (dacl.IsCanonical);
197 			Assert.AreEqual (2, dacl.Count);
198 
199 			CommonAce adminAce = (CommonAce)dacl [0];
200 			Assert.AreEqual (adminSid, adminAce.SecurityIdentifier);
201 			Assert.AreEqual (10, adminAce.AccessMask);
202 
203 			CommonAce userAce = (CommonAce)dacl [1];
204 			Assert.AreEqual (userSid, userAce.SecurityIdentifier);
205 			Assert.AreEqual (5, userAce.AccessMask);
206 		}
207 
208 		[Test]
DetectsNonCanonicalAndDoesNotMerge()209 		public void DetectsNonCanonicalAndDoesNotMerge ()
210 		{
211 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
212 
213 			RawAcl acl = MakeRawAcl(new GenericAce[] {
214 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
215 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null),
216 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
217 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null)
218 			});
219 
220 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
221 			Assert.IsFalse (dacl.IsCanonical);
222 			Assert.AreEqual (4, dacl.Count);
223 		}
224 
225 		[Test]
DoesNotMergeOrEvaluateOrderingForInherited()226 		public void DoesNotMergeOrEvaluateOrderingForInherited ()
227 		{
228 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
229 
230 			RawAcl acl = MakeRawAcl(new GenericAce[] {
231 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 1, sid, false, null),
232 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 2, sid, false, null),
233 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
234 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 8, sid, false, null)
235 			});
236 
237 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
238 			Assert.IsTrue (dacl.IsCanonical);
239 			Assert.AreEqual (4, dacl.Count);
240 		}
241 
242 		[Test]
SetterNotSupported()243 		public void SetterNotSupported ()
244 		{
245 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
246 
247 			RawAcl acl = MakeRawAcl(new GenericAce[] {
248 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 1, sid, false, null),
249 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 2, sid, false, null),
250 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null),
251 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 4, sid, false, null)
252 			});
253 
254 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
255 			Assert.IsTrue (dacl.IsCanonical);
256 			Assert.AreEqual (4, dacl.Count);
257 
258 			bool throws1 = false;
259 			try { dacl[0] = acl[0]; } catch (NotSupportedException) { throws1 = true; }
260 			Assert.IsTrue (throws1);
261 
262 			bool throws2 = false;
263 			try { dacl[0] = acl[2]; } catch (NotSupportedException) { throws2 = true; }
264 			Assert.IsTrue (throws2);
265 		}
266 
267 		// FIXME: Uncomment this once CompoundAce is implemented on Mono.
268 		/*
269 		[Test]
270 		public void CompoundAcesAreNotCanonical ()
271 		{
272 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
273 
274 			RawAcl acl = MakeRawAcl(new GenericAce[] {
275 				new CompoundAce (AceFlags.None, 1, CompoundAceType.Impersonation, sid)
276 			});
277 
278 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
279 			Assert.IsFalse (dacl.IsCanonical);
280 		}
281 		*/
282 
283 		[Test]
RemovesMeaninglessAces()284 		public void RemovesMeaninglessAces ()
285 		{
286 			RawAcl acl = GetRemovesMeaninglessAcesAcl ();
287 
288 			DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl);
289 			Assert.IsTrue (dacl1.IsCanonical);
290 			Assert.AreEqual (7, dacl1.Count);
291 			Assert.AreEqual (12, ((KnownAce)dacl1 [0]).AccessMask);
292 
293 			DiscretionaryAcl dacl2 = new DiscretionaryAcl (true, false, acl);
294 			Assert.IsTrue (dacl2.IsCanonical);
295 			Assert.AreEqual (8, dacl2.Count);
296 			Assert.AreEqual (12, ((KnownAce)dacl1 [0]).AccessMask);
297 		}
298 
299 		// shared with BinaryRoundtrip as well
GetRemovesMeaninglessAcesAcl()300 		static RawAcl GetRemovesMeaninglessAcesAcl ()
301 		{
302 			SecurityIdentifier sid = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null);
303 
304 			return MakeRawAcl(new GenericAce[] {
305 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 4, sid, false, null),
306 				new CommonAce (AceFlags.None, AceQualifier.AccessDenied, 8, sid, false, null), // merged
307 				new CommonAce (AceFlags.InheritOnly|AceFlags.ObjectInherit,
308 				               AceQualifier.AccessDenied, 42, sid, false, null), // removed ONLY if !IsContainer
309 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0, sid, false, null), // removed
310 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sid, false, null),
311 				new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 2, sid, false, null), // merged
312 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid, false, null),
313 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 2, sid, false, null),
314 				new ObjectAce (AceFlags.None, AceQualifier.AccessAllowed, 0, sid,
315 				               ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid (), false, null), // removed
316 				new ObjectAce (AceFlags.InheritOnly, AceQualifier.AccessAllowed, 1, sid,
317 				               ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.NewGuid (), false, null), // removed
318 				new ObjectAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 1, sid,
319 				               ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid (), false, null),
320 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 0, sid, false, null), // removed
321 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 4, sid, false, null),
322 				new CommonAce (AceFlags.Inherited, AceQualifier.AccessDenied, 4, sid, false, null),
323 				new CommonAce (AceFlags.Inherited, AceQualifier.SystemAlarm, 4, sid, false, null), // removed
324 				new CommonAce (AceFlags.Inherited, AceQualifier.SystemAudit, 4, sid, false, null) // removed
325 			});
326 		}
327 
328 		[Test]
BinaryRoundtrip()329 		public void BinaryRoundtrip ()
330 		{
331 			RawAcl acl = GetRemovesMeaninglessAcesAcl ();
332 
333 			DiscretionaryAcl dacl1 = new DiscretionaryAcl (false, false, acl);
334 			byte[] binaryForm1 = new byte[dacl1.BinaryLength];
335 			dacl1.GetBinaryForm (binaryForm1, 0);
336 
337 			DiscretionaryAcl dacl2 = new DiscretionaryAcl (false, false, new RawAcl (binaryForm1, 0));
338 			byte[] binaryForm2 = new byte[dacl2.BinaryLength];
339 			dacl2.GetBinaryForm (binaryForm2, 0);
340 
341 			Assert.AreEqual (binaryForm1.Length, binaryForm2.Length);
342 			for (int i = 0; i < binaryForm1.Length; i ++)
343 				Assert.AreEqual (binaryForm1 [i], binaryForm2 [i]);
344 		}
345 
346 		[Test]
ContiguousRangeSorting()347 		public void ContiguousRangeSorting ()
348 		{
349 			SecurityIdentifier[] sids = new SecurityIdentifier[] {
350 				new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null), // S-1-5-32-544
351 				new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null),	  // S-1-5-32-545
352 				new SecurityIdentifier (WellKnownSidType.WorldSid, null), 		  // S-1-1-0
353 				new SecurityIdentifier ("S-1-5-40"),
354 				new SecurityIdentifier ("S-1-5-30-123"),
355 				new SecurityIdentifier ("S-1-5-32-99"),
356 				new SecurityIdentifier ("S-1-5-23-45-67"),
357 				new SecurityIdentifier ("S-1-5-32-5432"),
358 				new SecurityIdentifier ("S-1-0-2"),
359 				new SecurityIdentifier ("S-1-6-0")
360 			};
361 
362 			GenericAce[] aces = new GenericAce[sids.Length];
363 			for (int i = 0; i < aces.Length; i ++)
364 				aces [i] = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 1, sids[i], false, null);
365 			RawAcl acl = MakeRawAcl (aces);
366 
367 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
368 			Assert.IsTrue (dacl.IsCanonical);
369 			Assert.AreEqual (sids[8], ((CommonAce)dacl [0]).SecurityIdentifier); // S-1-0-2
370 			Assert.AreEqual (sids[2], ((CommonAce)dacl [1]).SecurityIdentifier); // S-1-1-0
371 			Assert.AreEqual (sids[3], ((CommonAce)dacl [2]).SecurityIdentifier); // S-1-5-40
372 			Assert.AreEqual (sids[4], ((CommonAce)dacl [3]).SecurityIdentifier); // S-1-5-30-123
373 			Assert.AreEqual (sids[5], ((CommonAce)dacl [4]).SecurityIdentifier); // S-1-5-32-99
374 			Assert.AreEqual (sids[0], ((CommonAce)dacl [5]).SecurityIdentifier); // S-1-5-32-544
375 			Assert.AreEqual (sids[1], ((CommonAce)dacl [6]).SecurityIdentifier); // S-1-5-32-545
376 			Assert.AreEqual (sids[7], ((CommonAce)dacl [7]).SecurityIdentifier); // S-1-5-32-5432
377 			Assert.AreEqual (sids[6], ((CommonAce)dacl [8]).SecurityIdentifier); // S-1-5-23-45-67
378 			Assert.AreEqual (sids[9], ((CommonAce)dacl [9]).SecurityIdentifier); // S-1-6-0
379 		}
380 
MakeRawAcl(GenericAce[] aces)381 		static RawAcl MakeRawAcl (GenericAce[] aces)
382 		{
383 			RawAcl acl = new RawAcl (RawAcl.AclRevision, 0);
384 			for (int i = 0; i < aces.Length; i ++) { acl.InsertAce (i, aces [i]); }
385 			return acl;
386 		}
387 
ToUInt16(byte[] buffer, int offset)388 		static ushort ToUInt16 (byte[] buffer, int offset)
389 		{
390 			return (ushort)(buffer [offset] | buffer [offset + 1]);
391 		}
392 
393 		[Test]
InheritanceFlagsMergeForAccessMasksThatMatch()394 		public void InheritanceFlagsMergeForAccessMasksThatMatch ()
395 		{
396 			SecurityIdentifier sid = new SecurityIdentifier ("BU");
397 
398 			RawAcl acl = MakeRawAcl (new GenericAce[] {
399 				new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
400 				new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 1, sid, false, null)
401 			});
402 
403 			DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, acl);
404 			Assert.AreEqual (1, dacl.Count);
405 
406 			CommonAce ace = (CommonAce) dacl [0];
407 			Assert.AreEqual (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, ace.InheritanceFlags);
408 		}
409 
410 		[Test]
InheritanceFlagsDoNotMergeForAccessMasksThatAND()411 		public void InheritanceFlagsDoNotMergeForAccessMasksThatAND ()
412 		{
413 			SecurityIdentifier sid = new SecurityIdentifier ("BU");
414 
415 			RawAcl acl = MakeRawAcl (new GenericAce[] {
416 				new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
417 				new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 3, sid, false, null)
418 			});
419 
420 			DiscretionaryAcl dacl = new DiscretionaryAcl (true, false, acl);
421 			Assert.AreEqual (2, dacl.Count);
422 		}
423 
424 		[Test]
InheritanceFlagsAreClearedBeforeMergeCheckingWhenNotContainer()425 		public void InheritanceFlagsAreClearedBeforeMergeCheckingWhenNotContainer ()
426 		{
427 			SecurityIdentifier sid = new SecurityIdentifier ("BU");
428 
429 			RawAcl acl = MakeRawAcl (new GenericAce[] {
430 				new CommonAce (AceFlags.ContainerInherit, AceQualifier.AccessAllowed, 1, sid, false, null),
431 				new CommonAce (AceFlags.ObjectInherit, AceQualifier.AccessAllowed, 2, sid, false, null)
432 			});
433 
434 			DiscretionaryAcl dacl = new DiscretionaryAcl (false, false, acl);
435 			Assert.AreEqual (1, dacl.Count);
436 
437 			CommonAce ace = (CommonAce) dacl [0];
438 			Assert.AreEqual (3, ace.AccessMask);
439 			Assert.AreEqual (InheritanceFlags.None, ace.InheritanceFlags);
440 		}
441 	}
442 }
443 
444