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