Implemented SystemAcl. Common shared functionality moved to CommonAcl. Only missing...
authorJames Bellinger <jfb@zer7.com>
Tue, 3 Jul 2012 19:32:49 +0000 (15:32 -0400)
committerJames Bellinger <jfb@zer7.com>
Tue, 3 Jul 2012 19:40:01 +0000 (15:40 -0400)
Unit tests included - for SystemAcl they are based on DiscretionaryAcl's mostly,
with one extra and one somewhat changed since AuditFlags merge together unlike Allow/Deny.

Anyway, it should be practical to implement CommonSecurityDescriptor and friends with these classes working.

mcs/class/corlib/System.Security.AccessControl/CommonAcl.cs
mcs/class/corlib/System.Security.AccessControl/DiscretionaryAcl.cs
mcs/class/corlib/System.Security.AccessControl/SystemAcl.cs
mcs/class/corlib/Test/System.Security.AccessControl/SystemAclTest.cs [new file with mode: 0644]
mcs/class/corlib/corlib_test.dll.sources

index d932186b0c70fa65f76f2e2c952f49e6ceb01582..64a5db201aa716f5e0a397469c2172eef920c8fe 100644 (file)
@@ -241,10 +241,17 @@ namespace System.Security.AccessControl
                        
                        if (aceFlags1 != aceFlags2) {
                                if (accessMask1 != accessMask2) return null;
-                               if ((aceFlags1 & ~(AceFlags.ContainerInherit|AceFlags.ObjectInherit)) !=
-                                   (aceFlags2 & ~(AceFlags.ContainerInherit|AceFlags.ObjectInherit))) return null;
-                               aceFlagsNew = aceFlags1|aceFlags2;
-                               accessMaskNew = accessMask1;
+                               if ((aceFlags1 & ~(AceFlags.ContainerInherit|AceFlags.ObjectInherit)) ==
+                                   (aceFlags2 & ~(AceFlags.ContainerInherit|AceFlags.ObjectInherit))) {
+                                       aceFlagsNew = aceFlags1|aceFlags2; // merge InheritanceFlags
+                                       accessMaskNew = accessMask1;
+                               } else if ((aceFlags1 & ~(AceFlags.SuccessfulAccess|AceFlags.FailedAccess)) ==
+                                          (aceFlags2 & ~(AceFlags.SuccessfulAccess|AceFlags.FailedAccess))) {
+                                       aceFlagsNew = aceFlags1|aceFlags2; // merge AuditFlags
+                                       accessMaskNew = accessMask1;
+                               } else {
+                                       return null;
+                               }
                        } else {
                                aceFlagsNew = aceFlags1;
                                accessMaskNew = accessMask1|accessMask2;
@@ -315,6 +322,201 @@ namespace System.Security.AccessControl
                                }
                        }
                }
+               
+               // DiscretionaryAcl/SystemAcl shared implementation below...
+               internal void AddAce (AceQualifier aceQualifier,
+                                     SecurityIdentifier sid, int accessMask,
+                                     InheritanceFlags inheritanceFlags,
+                                     PropagationFlags propagationFlags,
+                                     AuditFlags auditFlags)
+               {
+                       QualifiedAce ace = AddAceGetQualifiedAce (aceQualifier, sid, accessMask,
+                                                                 inheritanceFlags, propagationFlags, auditFlags);
+                       AddAce (ace);
+               }
+               
+               internal void AddAce (AceQualifier aceQualifier,
+                                     SecurityIdentifier sid, int accessMask,
+                                     InheritanceFlags inheritanceFlags,
+                                     PropagationFlags propagationFlags,
+                                     AuditFlags auditFlags,
+                                     ObjectAceFlags objectFlags,
+                                     Guid objectType,
+                                     Guid inheritedObjectType)
+               {
+                       QualifiedAce ace = AddAceGetQualifiedAce (aceQualifier, sid, accessMask,
+                                                                 inheritanceFlags, propagationFlags, auditFlags,
+                                                                 objectFlags, objectType, inheritedObjectType);
+                       AddAce (ace);
+               }
+               
+               QualifiedAce AddAceGetQualifiedAce (AceQualifier aceQualifier,
+                                                   SecurityIdentifier sid, int accessMask,
+                                                   InheritanceFlags inheritanceFlags,
+                                                   PropagationFlags propagationFlags,
+                                                   AuditFlags auditFlags,
+                                                   ObjectAceFlags objectFlags,
+                                                   Guid objectType,
+                                                   Guid inheritedObjectType)
+               {
+                       if (!IsDS)
+                               throw new InvalidOperationException ("For this overload, IsDS must be true.");
+                               
+                       if (ObjectAceFlags.None == objectFlags)
+                               return AddAceGetQualifiedAce (aceQualifier, sid, accessMask,
+                                                             inheritanceFlags, propagationFlags, auditFlags);
+                       
+                       AceFlags flags = GetAceFlags (inheritanceFlags, propagationFlags, auditFlags);
+                       return new ObjectAce (flags, aceQualifier, accessMask, sid,
+                                             objectFlags, objectType, inheritedObjectType, false, null);
+               }
+               
+               QualifiedAce AddAceGetQualifiedAce (AceQualifier aceQualifier,
+                                                   SecurityIdentifier sid, int accessMask,
+                                                   InheritanceFlags inheritanceFlags,
+                                                   PropagationFlags propagationFlags,
+                                                   AuditFlags auditFlags)
+               {
+                       AceFlags flags = GetAceFlags (inheritanceFlags, propagationFlags, auditFlags);
+                       return new CommonAce (flags, aceQualifier, accessMask, sid, false, null);
+               }
+               
+               void AddAce (QualifiedAce newAce)
+               {
+                       RequireCanonicity ();
+                               
+                       int pos = GetAceInsertPosition (newAce.AceQualifier);
+                       raw_acl.InsertAce (pos, newAce);
+                       CleanAndRetestCanonicity ();
+               }
+               
+               internal abstract int GetAceInsertPosition (AceQualifier aceQualifier);
+               
+               AceFlags GetAceFlags (InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags)
+               {
+                       if (InheritanceFlags.None != inheritanceFlags && !IsContainer)
+                               throw new ArgumentException ("Flags only work with containers.", "inheritanceFlags");
+                       
+                       if (InheritanceFlags.None == inheritanceFlags && PropagationFlags.None != propagationFlags)
+                               throw new ArgumentException ("Propagation flags need inheritance flags.", "propagationFlags");
+                       
+                       AceFlags flags = AceFlags.None;
+                       if (0 != (InheritanceFlags.ContainerInherit & inheritanceFlags))
+                               flags |= AceFlags.ContainerInherit;
+                       if (0 != (InheritanceFlags.ObjectInherit & inheritanceFlags))
+                               flags |= AceFlags.ObjectInherit;
+                       if (0 != (PropagationFlags.InheritOnly & propagationFlags))
+                               flags |= AceFlags.InheritOnly;
+                       if (0 != (PropagationFlags.NoPropagateInherit & propagationFlags))
+                               flags |= AceFlags.NoPropagateInherit;
+                       if (0 != (AuditFlags.Success & auditFlags))
+                               flags |= AceFlags.SuccessfulAccess;
+                       if (0 != (AuditFlags.Failure & auditFlags))
+                               flags |= AceFlags.FailedAccess;
+                       return flags;
+               }
+               
+               internal void RemoveAceSpecific (AceQualifier aceQualifier,
+                                                SecurityIdentifier sid,
+                                                int accessMask,
+                                                InheritanceFlags inheritanceFlags,
+                                                PropagationFlags propagationFlags,
+                                                AuditFlags auditFlags)
+               {
+                       RequireCanonicity ();
+                       RemoveAces<CommonAce> (ace =>
+                       {
+                               if (ace.AccessMask != accessMask) return false;
+                               if (ace.AceQualifier != aceQualifier) return false;
+                               if (ace.SecurityIdentifier != sid) return false;
+                               if (ace.InheritanceFlags != inheritanceFlags) return false;
+                               if (InheritanceFlags.None != inheritanceFlags)
+                                       if (ace.PropagationFlags != propagationFlags) return false;
+                               if (ace.AuditFlags != auditFlags) return false;
+                               return true;
+                       });
+                       CleanAndRetestCanonicity ();
+               }
+               
+               internal void RemoveAceSpecific (AceQualifier aceQualifier,
+                                                SecurityIdentifier sid,
+                                                int accessMask,
+                                                InheritanceFlags inheritanceFlags,
+                                                PropagationFlags propagationFlags,
+                                                AuditFlags auditFlags,
+                                                ObjectAceFlags objectFlags,
+                                                Guid objectType,
+                                                Guid inheritedObjectType)
+               {
+                       if (!IsDS)
+                               throw new InvalidOperationException ("For this overload, IsDS must be true.");
+                               
+                       if (ObjectAceFlags.None == objectFlags) {
+                               RemoveAceSpecific (aceQualifier, sid, accessMask, inheritanceFlags, propagationFlags, auditFlags);
+                               return;
+                       }
+
+                       RequireCanonicity ();
+                       RemoveAces<ObjectAce> (ace =>
+                       {
+                               if (ace.AccessMask != accessMask) return false;
+                               if (ace.AceQualifier != aceQualifier) return false;
+                               if (ace.SecurityIdentifier != sid) return false;
+                               if (ace.InheritanceFlags != inheritanceFlags) return false;
+                               if (InheritanceFlags.None != inheritanceFlags)
+                                       if (ace.PropagationFlags != propagationFlags) return false;
+                               if (ace.AuditFlags != auditFlags) return false;
+                               if (ace.ObjectAceFlags != objectFlags) return false;
+                               if (0 != (objectFlags & ObjectAceFlags.ObjectAceTypePresent))
+                                       if (ace.ObjectAceType != objectType) return false;
+                               if (0 != (objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent))
+                                       if (ace.InheritedObjectAceType != objectType) return false;
+                               return true;
+                       });
+                       CleanAndRetestCanonicity ();
+               }
+               
+               internal void SetAce (AceQualifier aceQualifier,
+                                     SecurityIdentifier sid,
+                                     int accessMask,
+                                     InheritanceFlags inheritanceFlags,
+                                     PropagationFlags propagationFlags,
+                                     AuditFlags auditFlags)
+               {
+                       QualifiedAce ace = AddAceGetQualifiedAce (aceQualifier, sid, accessMask,
+                                                                 inheritanceFlags, propagationFlags, auditFlags);
+                       SetAce (ace);
+               }
+               
+               internal void SetAce (AceQualifier aceQualifier,
+                                     SecurityIdentifier sid,
+                                     int accessMask,
+                                     InheritanceFlags inheritanceFlags,
+                                     PropagationFlags propagationFlags,
+                                     AuditFlags auditFlags,
+                                     ObjectAceFlags objectFlags,
+                                     Guid objectType,
+                                     Guid inheritedObjectType)
+               {
+                       QualifiedAce ace = AddAceGetQualifiedAce (aceQualifier, sid, accessMask,
+                                                                 inheritanceFlags, propagationFlags, auditFlags,
+                                                                 objectFlags, objectType, inheritedObjectType);
+                       SetAce (ace);
+               }
+               
+               void SetAce (QualifiedAce newAce)
+               {
+                       RequireCanonicity ();
+                       
+                       RemoveAces<QualifiedAce> (oldAce =>
+                       {
+                               return oldAce.AceQualifier == newAce.AceQualifier &&
+                                      oldAce.SecurityIdentifier == newAce.SecurityIdentifier;
+                       });
+                       CleanAndRetestCanonicity ();
+                                               
+                       AddAce (newAce);
+               }
        }
 }
 
index 8ec25dccc1c2ad0a321c4b91eaa4f2a6a4ee7dc9..ba7167c3d04fe9477152cd567a048836cb3fbb8f 100644 (file)
@@ -55,9 +55,8 @@ namespace System.Security.AccessControl
                                       InheritanceFlags inheritanceFlags,
                                       PropagationFlags propagationFlags)
                {
-                       QualifiedAce ace = AddAccessGetQualifiedAce (accessType, sid, accessMask,
-                                                                    inheritanceFlags, propagationFlags);
-                       AddAccess (ace);
+                       AddAce (GetAceQualifier (accessType), sid, accessMask,
+                               inheritanceFlags, propagationFlags, AuditFlags.None);
                }
                
                public void AddAccess (AccessControlType accessType,
@@ -68,54 +67,9 @@ namespace System.Security.AccessControl
                                       Guid objectType,
                                       Guid inheritedObjectType)
                {
-                       QualifiedAce ace = AddAccessGetQualifiedAce (accessType, sid, accessMask,
-                                                                    inheritanceFlags, propagationFlags,
-                                                                    objectFlags, objectType, inheritedObjectType);
-                       AddAccess (ace);
-               }
-
-               QualifiedAce AddAccessGetQualifiedAce (AccessControlType accessType,
-                                                      SecurityIdentifier sid, int accessMask,
-                                                      InheritanceFlags inheritanceFlags,
-                                                      PropagationFlags propagationFlags,
-                                                      ObjectAceFlags objectFlags,
-                                                      Guid objectType,
-                                                      Guid inheritedObjectType)
-               {
-                       if (!IsDS)
-                               throw new InvalidOperationException ("For this overload, IsDS must be true.");
-                               
-                       if (ObjectAceFlags.None == objectFlags)
-                               return AddAccessGetQualifiedAce (accessType, sid, accessMask, inheritanceFlags, propagationFlags);
-                       
-                       AceQualifier qualifier = GetAceQualifier (accessType);
-                       AceFlags flags = GetAceFlags (inheritanceFlags, propagationFlags);
-                       return new ObjectAce (flags, qualifier, accessMask, sid,
-                                             objectFlags, objectType, inheritedObjectType, false, null);
-               }
-               
-               QualifiedAce AddAccessGetQualifiedAce (AccessControlType accessType,
-                                                      SecurityIdentifier sid, int accessMask,
-                                                      InheritanceFlags inheritanceFlags,
-                                                      PropagationFlags propagationFlags)
-               {
-                       AceQualifier qualifier = GetAceQualifier (accessType);
-                       AceFlags flags = GetAceFlags (inheritanceFlags, propagationFlags);
-                       return new CommonAce (flags, qualifier, accessMask, sid, false, null);
-               }
-               
-               void AddAccess (QualifiedAce newAce)
-               {
-                       RequireCanonicity ();
-                               
-                       int pos; // Canonical order is explicit deny, explicit allow, inherited.
-                       if (AceQualifier.AccessAllowed == newAce.AceQualifier)
-                               pos = GetCanonicalExplicitDenyAceCount ();
-                       else
-                               pos = 0;
-                       
-                       raw_acl.InsertAce (pos, newAce);
-                       CleanAndRetestCanonicity ();
+                       AddAce (GetAceQualifier (accessType), sid, accessMask,
+                               inheritanceFlags, propagationFlags, AuditFlags.None,
+                               objectFlags, objectType, inheritedObjectType);
                }
                
                public bool RemoveAccess (AccessControlType accessType,
@@ -145,19 +99,8 @@ namespace System.Security.AccessControl
                                                  InheritanceFlags inheritanceFlags,
                                                  PropagationFlags propagationFlags)
                {
-                       RequireCanonicity ();
-                       AceQualifier qualifier = GetAceQualifier (accessType);
-                       RemoveAces<CommonAce> (ace =>
-                       {
-                               if (ace.AccessMask != accessMask) return false;
-                               if (ace.AceQualifier != qualifier) return false;
-                               if (ace.SecurityIdentifier != sid) return false;
-                               if (ace.InheritanceFlags != inheritanceFlags) return false;
-                               if (InheritanceFlags.None != inheritanceFlags)
-                                       if (ace.PropagationFlags != propagationFlags) return false;
-                               return true;
-                       });
-                       CleanAndRetestCanonicity ();
+                       RemoveAceSpecific (GetAceQualifier (accessType), sid, accessMask,
+                                          inheritanceFlags, propagationFlags, AuditFlags.None);
                }
                
                public void RemoveAccessSpecific (AccessControlType accessType,
@@ -169,32 +112,9 @@ namespace System.Security.AccessControl
                                                  Guid objectType,
                                                  Guid inheritedObjectType)
                {
-                       if (!IsDS)
-                               throw new InvalidOperationException ("For this overload, IsDS must be true.");
-                               
-                       if (ObjectAceFlags.None == objectFlags) {
-                               RemoveAccessSpecific (accessType, sid, accessMask, inheritanceFlags, propagationFlags);
-                               return;
-                       }
-
-                       RequireCanonicity ();
-                       AceQualifier qualifier = GetAceQualifier (accessType);
-                       RemoveAces<ObjectAce> (ace =>
-                       {
-                               if (ace.AccessMask != accessMask) return false;
-                               if (ace.AceQualifier != qualifier) return false;
-                               if (ace.SecurityIdentifier != sid) return false;
-                               if (ace.InheritanceFlags != inheritanceFlags) return false;
-                               if (InheritanceFlags.None != inheritanceFlags)
-                                       if (ace.PropagationFlags != propagationFlags) return false;
-                               if (ace.ObjectAceFlags != objectFlags) return false;
-                               if (0 != (objectFlags & ObjectAceFlags.ObjectAceTypePresent))
-                                       if (ace.ObjectAceType != objectType) return false;
-                               if (0 != (objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent))
-                                       if (ace.InheritedObjectAceType != objectType) return false;
-                               return true;
-                       });
-                       CleanAndRetestCanonicity ();
+                       RemoveAceSpecific (GetAceQualifier (accessType), sid, accessMask,
+                                          inheritanceFlags, propagationFlags, AuditFlags.None,
+                                          objectFlags, objectType, inheritedObjectType);
                }
                
                public void SetAccess (AccessControlType accessType,
@@ -203,9 +123,8 @@ namespace System.Security.AccessControl
                                       InheritanceFlags inheritanceFlags,
                                       PropagationFlags propagationFlags)
                {
-                       QualifiedAce ace = AddAccessGetQualifiedAce (accessType, sid, accessMask,
-                                                                    inheritanceFlags, propagationFlags);
-                       SetAccess (ace);
+                       SetAce (GetAceQualifier (accessType), sid, accessMask,
+                               inheritanceFlags, propagationFlags, AuditFlags.None);
                }
                
                public void SetAccess (AccessControlType accessType,
@@ -217,26 +136,11 @@ namespace System.Security.AccessControl
                                       Guid objectType,
                                       Guid inheritedObjectType)
                {
-                       QualifiedAce ace = AddAccessGetQualifiedAce (accessType, sid, accessMask,
-                                                                    inheritanceFlags, propagationFlags,
-                                                                    objectFlags, objectType, inheritedObjectType);
-                       SetAccess (ace);
-               }
-
-               void SetAccess (QualifiedAce newAce)
-               {
-                       RequireCanonicity ();
-                       
-                       RemoveAces<QualifiedAce> (oldAce =>
-                       {
-                               return oldAce.AceQualifier == newAce.AceQualifier &&
-                                      oldAce.SecurityIdentifier == newAce.SecurityIdentifier;
-                       });
-                       CleanAndRetestCanonicity ();
-                                               
-                       AddAccess (newAce);
+                       SetAce (GetAceQualifier (accessType), sid, accessMask,
+                               inheritanceFlags, propagationFlags, AuditFlags.None,
+                               objectFlags, objectType, inheritedObjectType);
                }
-
+               
                internal override void ApplyCanonicalSortToExplicitAces ()
                {
                        int explicitCount = GetCanonicalExplicitAceCount ();
@@ -246,37 +150,13 @@ namespace System.Security.AccessControl
                        ApplyCanonicalSortToExplicitAces (explicitDenys, explicitCount - explicitDenys);
                }
                
-               internal override bool IsAceMeaningless (GenericAce ace)
+               internal override int GetAceInsertPosition (AceQualifier aceQualifier)
                {
-                       if (base.IsAceMeaningless (ace)) return true;
-                       
-                       QualifiedAce qace = ace as QualifiedAce;
-                       if (null != qace) {
-                               return !(AceQualifier.AccessAllowed == qace.AceQualifier ||
-                                        AceQualifier.AccessDenied  == qace.AceQualifier);
-                       }
-
-                       return false;
-               }
-               
-               AceFlags GetAceFlags (InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
-               {
-                       if (InheritanceFlags.None != inheritanceFlags && !IsContainer)
-                               throw new ArgumentException ("Flags only work with containers.", "inheritanceFlags");
-                       
-                       if (InheritanceFlags.None == inheritanceFlags && PropagationFlags.None != propagationFlags)
-                               throw new ArgumentException ("Propagation flags need inheritance flags.", "propagationFlags");
-                       
-                       AceFlags flags = AceFlags.None;
-                       if (0 != ((InheritanceFlags.ContainerInherit) & inheritanceFlags))
-                               flags |= AceFlags.ContainerInherit;
-                       if (0 != ((InheritanceFlags.ObjectInherit) & inheritanceFlags))
-                               flags |= AceFlags.ObjectInherit;
-                       if (0 != ((PropagationFlags.InheritOnly) & propagationFlags))
-                               flags |= AceFlags.InheritOnly;
-                       if (0 != ((PropagationFlags.NoPropagateInherit) & propagationFlags))
-                               flags |= AceFlags.NoPropagateInherit;
-                       return flags;
+                       // Canonical order for DACLs is explicit deny, explicit allow, inherited.
+                       if (AceQualifier.AccessAllowed == aceQualifier)
+                               return GetCanonicalExplicitDenyAceCount ();
+                       else
+                               return 0;
                }
                
                static AceQualifier GetAceQualifier (AccessControlType accessType)
@@ -288,6 +168,20 @@ namespace System.Security.AccessControl
                        else
                                throw new ArgumentOutOfRangeException ("accessType");
                }
+               
+               internal override bool IsAceMeaningless (GenericAce ace)
+               {
+                       if (base.IsAceMeaningless (ace)) return true;
+                       if (AuditFlags.None != ace.AuditFlags) return true;
+                       
+                       QualifiedAce qace = ace as QualifiedAce;
+                       if (null != qace) {
+                               if (!(AceQualifier.AccessAllowed == qace.AceQualifier ||
+                                     AceQualifier.AccessDenied  == qace.AceQualifier)) return true;
+                       }
+
+                       return false;
+               }
        }
 }
 
index 11809523c8f2229cb2855d633606a7195a6712bf..5005bedda40b96e359ee491fa6eb2c4bf73797c5 100644 (file)
@@ -4,8 +4,10 @@
 // Authors:
 //     Dick Porter  <dick@ximian.com>
 //     Atsushi Enomoto  <atsushi@ximian.com>
+//     James Bellinger  <jfb@zer7.com>
 //
 // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2012      James Bellinger
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -53,8 +55,8 @@ namespace System.Security.AccessControl
                                      InheritanceFlags inheritanceFlags,
                                      PropagationFlags propagationFlags)
                {
-                       // CommonAce?
-                       throw new NotImplementedException ();
+                       AddAce (AceQualifier.SystemAudit, sid, accessMask,
+                               inheritanceFlags, propagationFlags, auditFlags);
                }
                
                public void AddAudit (AuditFlags auditFlags,
@@ -65,8 +67,9 @@ namespace System.Security.AccessControl
                                      Guid objectType,
                                      Guid inheritedObjectType)
                {
-                       // ObjectAce?
-                       throw new NotImplementedException ();
+                       AddAce (AceQualifier.SystemAudit, sid, accessMask,
+                               inheritanceFlags, propagationFlags, auditFlags,
+                               objectFlags, objectType, inheritedObjectType);
                }
                
                public bool RemoveAudit (AuditFlags auditFlags,
@@ -96,7 +99,9 @@ namespace System.Security.AccessControl
                                                 InheritanceFlags inheritanceFlags,
                                                 PropagationFlags propagationFlags)
                {
-                       throw new NotImplementedException ();
+                       RemoveAceSpecific (AceQualifier.SystemAudit, sid, accessMask,
+                                          inheritanceFlags, propagationFlags, auditFlags);
+
                }
                
                public void RemoveAuditSpecific (AuditFlags auditFlags,
@@ -108,7 +113,10 @@ namespace System.Security.AccessControl
                                                 Guid objectType,
                                                 Guid inheritedObjectType)
                {
-                       throw new NotImplementedException ();
+                       RemoveAceSpecific (AceQualifier.SystemAudit, sid, accessMask,
+                                          inheritanceFlags, propagationFlags, auditFlags,
+                                          objectFlags, objectType, inheritedObjectType);
+
                }
                
                public void SetAudit (AuditFlags auditFlags,
@@ -117,7 +125,8 @@ namespace System.Security.AccessControl
                                      InheritanceFlags inheritanceFlags,
                                      PropagationFlags propagationFlags)
                {
-                       throw new NotImplementedException ();
+                       SetAce (AceQualifier.SystemAudit, sid, accessMask,
+                               inheritanceFlags, propagationFlags, auditFlags);
                }
                
                public void SetAudit (AuditFlags auditFlags,
@@ -129,7 +138,9 @@ namespace System.Security.AccessControl
                                      Guid objectType,
                                      Guid inheritedObjectType)
                {
-                       throw new NotImplementedException ();
+                       SetAce (AceQualifier.SystemAudit, sid, accessMask,
+                               inheritanceFlags, propagationFlags, auditFlags,
+                               objectFlags, objectType, inheritedObjectType);
                }
                
                internal override void ApplyCanonicalSortToExplicitAces ()
@@ -138,18 +149,30 @@ namespace System.Security.AccessControl
                        ApplyCanonicalSortToExplicitAces (0, explicitCount);
                }
                
+               internal override int GetAceInsertPosition (AceQualifier aceQualifier)
+               {
+                       return 0;
+               }
+               
                internal override bool IsAceMeaningless (GenericAce ace)
                {
                        if (base.IsAceMeaningless (ace)) return true;
+                       if (!IsValidAuditFlags (ace.AuditFlags)) return true;
                        
                        QualifiedAce qace = ace as QualifiedAce;
                        if (null != qace) {
-                               return !(AceQualifier.SystemAudit == qace.AceQualifier ||
-                                        AceQualifier.SystemAlarm == qace.AceQualifier);
+                               if (!(AceQualifier.SystemAudit == qace.AceQualifier ||
+                                     AceQualifier.SystemAlarm == qace.AceQualifier)) return true;
                        }
                        
                        return false;
                }
+               
+               static bool IsValidAuditFlags (AuditFlags auditFlags)
+               {
+                       return auditFlags != AuditFlags.None &&
+                              auditFlags == ((AuditFlags.Success|AuditFlags.Failure) & auditFlags);
+               }
        }
 }
 
diff --git a/mcs/class/corlib/Test/System.Security.AccessControl/SystemAclTest.cs b/mcs/class/corlib/Test/System.Security.AccessControl/SystemAclTest.cs
new file mode 100644 (file)
index 0000000..e04594d
--- /dev/null
@@ -0,0 +1,182 @@
+// SystemAclTest.cs - NUnit Test Cases for SystemAcl
+//
+// Authors:
+//     James Bellinger  <jfb@zer7.com>
+//
+// Copyright (C) 2012 James Bellinger
+
+using System;
+using System.Collections.Generic;
+using System.Security.AccessControl;
+using System.Security.Principal;
+using NUnit.Framework;
+
+namespace MonoTests.System.Security.AccessControl
+{
+       [TestFixture]
+       public class SystemAclTest
+       {
+               [Test]
+               public void StartsEmpty ()
+               {
+                       Assert.AreEqual (0, new SystemAcl (false, false, 0).Count);
+                       //Assert.AreEqual (0, new SystemAcl (false, false, null).Count);
+                       // ^ MS.NET has a bug here and throws, contrary to their own documentation.
+               }
+
+               [Test]
+               public void AddAuditMergesFlags ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, false, 0);
+
+                       sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None);
+                       sacl.AddAudit (AuditFlags.Failure, sid, 1, InheritanceFlags.None, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+
+                       CommonAce ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (AuditFlags.Success|AuditFlags.Failure, ace.AuditFlags);
+               }
+
+               [Test]
+               public void AddAuditCommonAce ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, false, 0);
+
+                       sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+
+                       CommonAce ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (AuditFlags.Success, ace.AuditFlags);
+                       Assert.AreEqual (1, ace.AccessMask);
+                       Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
+                       Assert.IsFalse (ace.IsInherited);
+               }
+
+               [Test]
+               public void AddAuditCommonAceUsingDSOverload ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, true, 0);
+
+                       sacl.AddAudit (AuditFlags.Failure, sid, 1, InheritanceFlags.None, PropagationFlags.None,
+                                      ObjectAceFlags.None, Guid.NewGuid (), Guid.NewGuid ());
+                       Assert.AreEqual (1, sacl.Count);
+
+                       CommonAce ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (AuditFlags.Failure, ace.AuditFlags);
+                       Assert.AreEqual (1, ace.AccessMask);
+                       Assert.AreEqual ("S-1-5-32-544", ace.SecurityIdentifier.Value);
+                       Assert.IsFalse (ace.IsInherited);
+               }
+
+               [Test]
+               public void AddAuditObjectAceAndCommonAce ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, true, 0);
+
+                       sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None,
+                                      ObjectAceFlags.ObjectAceTypePresent, Guid.NewGuid (), Guid.Empty);
+                       sacl.AddAudit (AuditFlags.Success, sid, 1, InheritanceFlags.None, PropagationFlags.None,
+                                      ObjectAceFlags.None, Guid.Empty, Guid.Empty);
+                       Assert.AreEqual (2, sacl.Count);
+
+                       CommonAce cace = (CommonAce)sacl [0];
+                       Assert.AreEqual (1, cace.AccessMask);
+                       Assert.AreEqual ("S-1-5-32-544", cace.SecurityIdentifier.Value);
+                       Assert.IsFalse (cace.IsCallback);
+                       Assert.IsFalse (cace.IsInherited);
+
+                       ObjectAce oace = (ObjectAce)sacl [1];
+                       Assert.AreEqual (1, oace.AccessMask);
+                       Assert.AreEqual ("S-1-5-32-544", oace.SecurityIdentifier.Value);
+                       Assert.IsFalse (oace.IsCallback);
+                       Assert.IsFalse (oace.IsInherited);
+
+                       sacl.AddAudit (AuditFlags.Success, sid, 2, InheritanceFlags.None, PropagationFlags.None,
+                                      ObjectAceFlags.None, Guid.Empty, Guid.Empty);
+                       Assert.AreEqual (2, sacl.Count);
+
+                       CommonAce cace2 = (CommonAce)sacl [0];
+                       Assert.AreEqual (3, cace2.AccessMask);
+               }
+
+               [Test]
+               public void RemoveSpecific ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, false, 0);
+
+                       RemoveSpecificBegin (sid, sacl, InheritanceFlags.None);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None);
+                       Assert.AreEqual (0, sacl.Count);
+               }
+
+               [Test]
+               public void RemoveSpecificUsingDSOverload ()
+               {
+                       SecurityIdentifier sid = new SecurityIdentifier ("BA");
+                       SystemAcl sacl = new SystemAcl (false, true, 0);
+
+                       RemoveSpecificBegin (sid, sacl, InheritanceFlags.None);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None,
+                                                 ObjectAceFlags.ObjectAceTypePresent, Guid.Empty, Guid.Empty);
+                       Assert.AreEqual (1, sacl.Count);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3, InheritanceFlags.None, PropagationFlags.None,
+                                                 ObjectAceFlags.None, Guid.Empty, Guid.Empty);
+                       Assert.AreEqual (0, sacl.Count);
+               }
+
+               void RemoveSpecificBegin (SecurityIdentifier sid, SystemAcl sacl, InheritanceFlags inheritanceFlags)
+               {
+                       SecurityIdentifier otherSid = new SecurityIdentifier ("BU");
+
+                       sacl.AddAudit (AuditFlags.Success, sid, 3, inheritanceFlags, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+                       sacl.RemoveAuditSpecific (AuditFlags.Failure, sid, 1, inheritanceFlags, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, otherSid, 1, inheritanceFlags, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 1, inheritanceFlags, PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+                       Assert.AreEqual (3, ((CommonAce)sacl [0]).AccessMask);
+                       sacl.RemoveAuditSpecific (AuditFlags.Success, sid, 3,
+                                                 inheritanceFlags ^ InheritanceFlags.ContainerInherit,
+                                                 PropagationFlags.None);
+                       Assert.AreEqual (1, sacl.Count);
+               }
+
+               [Test]
+               public void SetAudit ()
+               {
+                       SecurityIdentifier adminSid = new SecurityIdentifier ("BA"); // S-1-5-32-544
+                       SecurityIdentifier userSid = new SecurityIdentifier ("BU"); // S-1-5-32-545
+
+                       SystemAcl sacl = new SystemAcl (true, false, 0);
+                       sacl.SetAudit (AuditFlags.Success, adminSid, 1, InheritanceFlags.ObjectInherit, PropagationFlags.None);
+                       sacl.SetAudit (AuditFlags.Success, userSid, 2, InheritanceFlags.None, PropagationFlags.None);
+                       Assert.AreEqual (2, sacl.Count);
+
+                       CommonAce ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (adminSid, ace.SecurityIdentifier);
+                       Assert.AreEqual (1, ace.AccessMask);
+
+                       sacl.SetAudit (AuditFlags.Success, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
+                       Assert.AreNotEqual (4, ace.AccessMask);
+                       ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (4, ace.AccessMask);
+
+                       sacl.SetAudit (AuditFlags.Failure, adminSid, 4, InheritanceFlags.ObjectInherit, PropagationFlags.None);
+                       Assert.AreEqual (2, sacl.Count);
+                       ace = (CommonAce)sacl [0];
+                       Assert.AreEqual (AuditFlags.Failure, ace.AuditFlags);
+                       Assert.AreEqual (adminSid, ace.SecurityIdentifier);
+                       ace = (CommonAce)sacl [1];
+                       Assert.AreEqual (AuditFlags.Success, ace.AuditFlags);
+                       Assert.AreEqual (userSid, ace.SecurityIdentifier);
+               }
+       }
+}
+
index 82c91cf4696359f62bcb36b0357345d09ae0ba86..0f9823cf4c04ed092ee9b9820729e340af1fc87c 100644 (file)
@@ -213,6 +213,7 @@ System.Security.AccessControl/ObjectAceTest.cs
 System.Security.AccessControl/ObjectSecurity_TTest.cs
 System.Security.AccessControl/RawAclTest.cs
 System.Security.AccessControl/RawSecurityDescriptorTest.cs
+System.Security.AccessControl/SystemAclTest.cs
 System.Security.Cryptography/AllTests2.cs
 System.Security.Cryptography/AsymmetricAlgorithmTest.cs
 System.Security.Cryptography/CipherModeTest.cs