CommonObjectSecurity.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Security / AccessControl / CommonObjectSecurity.cs / 1 / CommonObjectSecurity.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Classes:  Common Object Security class 
**
** 
===========================================================*/

using Microsoft.Win32;
using System; 
using System.Collections;
using System.Security.Principal; 
using System.Security.Permissions; 
using System.Runtime.InteropServices;
 
namespace System.Security.AccessControl
{

    [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")] 
    public abstract class CommonObjectSecurity: ObjectSecurity
    { 
        #region Constructors 

        protected CommonObjectSecurity( bool isContainer ) 
            : base( isContainer, false )
        {
        }
 
        internal CommonObjectSecurity( CommonSecurityDescriptor securityDescriptor )
            : base( securityDescriptor ) 
        { 
        }
 
        #endregion

        #region Private Methods
 
        private AuthorizationRuleCollection GetRules( bool access, bool includeExplicit, bool includeInherited, System.Type targetType )
        { 
            ReadLock(); 

            try 
            {
                AuthorizationRuleCollection result = new AuthorizationRuleCollection();

                if ( !SecurityIdentifier.IsValidTargetTypeStatic( targetType )) 
                {
                    throw new ArgumentException( 
                        Environment.GetResourceString("Arg_MustBeIdentityReferenceType"), 
                        "targetType" );
                } 

                CommonAcl acl = null;

                if ( access ) 
                {
                    if (( _securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent ) != 0) 
                    { 
                        acl = _securityDescriptor.DiscretionaryAcl;
                    } 
                }
                else // !access == audit
                {
                    if (( _securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent ) != 0) 
                    {
                        acl = _securityDescriptor.SystemAcl; 
                    } 
                }
 
                if ( acl == null )
                {
                    //
                    // The required ACL was not present; return an empty collection. 
                    //
                    return result; 
                } 

                IdentityReferenceCollection irTarget = null; 

                if ( targetType != typeof( SecurityIdentifier ))
                {
                    IdentityReferenceCollection irSource = new IdentityReferenceCollection( acl.Count ); 

                    for ( int i = 0; i < acl.Count; i++ ) 
                    { 
                        //
                        // Calling the indexer on a common ACL results in cloning, 
                        // (which would not be the case if we were to use the internal RawAcl property)
                        // but also ensures that the resulting order of ACEs is proper
                        // However, this is a big price to pay - cloning all the ACEs just so that
                        // the canonical order could be ascertained just once. 
                        // A better way would be to have an internal method that would canonicalize the ACL
                        // and call it once, then use the RawAcl. 
                        // 
                        CommonAce ace = acl[i] as CommonAce;
                        if (AceNeedsTranslation(ace, access, includeExplicit, includeInherited)) 
                        {
                            irSource.Add( ace.SecurityIdentifier );
                        }
                    } 

                    irTarget = irSource.Translate( targetType ); 
                } 

                int targetIndex = 0; 
                for ( int i = 0; i < acl.Count; i++ )
                {
                    //
                    // Calling the indexer on a common ACL results in cloning, 
                    // (which would not be the case if we were to use the internal RawAcl property)
                    // but also ensures that the resulting order of ACEs is proper 
                    // However, this is a big price to pay - cloning all the ACEs just so that 
                    // the canonical order could be ascertained just once.
                    // A better way would be to have an internal method that would canonicalize the ACL 
                    // and call it once, then use the RawAcl.
                    //

                    CommonAce ace = acl[i] as CommonAce; 
                    if (AceNeedsTranslation(ace, access, includeExplicit, includeInherited))
                    { 
                        IdentityReference iref = ( targetType == typeof(SecurityIdentifier )) ? ace.SecurityIdentifier : irTarget[targetIndex++]; 

                        if ( access ) 
                        {
                            AccessControlType type;

                            if (ace.AceQualifier == AceQualifier.AccessAllowed) 
                            {
                                type = AccessControlType.Allow; 
                            } 
                            else
                            { 
                                type = AccessControlType.Deny;
                            }

                            result.AddRule( 
                                AccessRuleFactory(
                                    iref, 
                                    ace.AccessMask, 
                                    ace.IsInherited,
                                    ace.InheritanceFlags, 
                                    ace.PropagationFlags,
                                    type ));
                        }
                        else 
                        {
                            result.AddRule( 
                                AuditRuleFactory( 
                                    iref,
                                    ace.AccessMask, 
                                    ace.IsInherited,
                                    ace.InheritanceFlags,
                                    ace.PropagationFlags,
                                    ace.AuditFlags)); 
                        }
                    } 
                } 

                return result; 
            }
            finally
            {
                ReadUnlock(); 
            }
        } 
 
        private bool AceNeedsTranslation(CommonAce ace, bool isAccessAce, bool includeExplicit, bool includeInherited)
        { 
            if ( ace == null )
            {
                //
                // Only consider common ACEs 
                //
 
                return false; 
            }
 
            if ( isAccessAce )
            {
                if ( ace.AceQualifier != AceQualifier.AccessAllowed &&
                    ace.AceQualifier != AceQualifier.AccessDenied ) 
                {
                    return false; 
                } 
            }
            else 
            {
                if ( ace.AceQualifier != AceQualifier.SystemAudit )
                {
                    return false; 
                }
            } 
 
            if (( includeExplicit &&
                (( ace.AceFlags & AceFlags.Inherited ) == 0 )) || 
                ( includeInherited &&
                (( ace.AceFlags & AceFlags.Inherited ) != 0 )))
            {
                return true; 
            }
 
            return false; 
        }
 
        //
        // Modifies the DACL
        //
        protected override bool ModifyAccess(AccessControlModification modification, AccessRule rule, out bool modified) 
        {
            WriteLock(); 
            try 
            {
                bool result = true; 

                if ( rule == null )
                {
                    throw new ArgumentNullException( "rule" ); 
                }
 
                if ( _securityDescriptor.DiscretionaryAcl == null ) 
                {
                    if ( modification == AccessControlModification.Remove || 
                        modification == AccessControlModification.RemoveAll ||
                        modification == AccessControlModification.RemoveSpecific )
                    {
                        modified = false; 
                        return result;
                    } 
 
                    _securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl( IsContainer, IsDS, GenericAcl.AclRevision, 1 );
                    _securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent); 
                }

                SecurityIdentifier sid = rule.IdentityReference.Translate( typeof( SecurityIdentifier )) as SecurityIdentifier;
 
                if ( rule.AccessControlType == AccessControlType.Allow )
                { 
                    switch ( modification ) 
                    {
                        case AccessControlModification.Add: 
                            _securityDescriptor.DiscretionaryAcl.AddAccess( AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break;

                        case AccessControlModification.Set: 
                            _securityDescriptor.DiscretionaryAcl.SetAccess( AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break; 
 
                        case AccessControlModification.Reset:
                            _securityDescriptor.DiscretionaryAcl.RemoveAccess( AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 0 ); 
                            _securityDescriptor.DiscretionaryAcl.SetAccess( AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break;

                        case AccessControlModification.Remove: 
                            result = _securityDescriptor.DiscretionaryAcl.RemoveAccess( AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break; 
 
                        case AccessControlModification.RemoveAll:
                            result = _securityDescriptor.DiscretionaryAcl.RemoveAccess( AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 0 ); 
                            if ( result == false )
                            {
                                BCLDebug.Assert( false, "Invalid operation" );
                                throw new SystemException(); 
                            }
 
                            break; 

                        case AccessControlModification.RemoveSpecific: 
                            _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific( AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break;

                        default : 
                            throw new ArgumentOutOfRangeException(
                                "modification", 
                                Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); 
                    }
                } 
                else if ( rule.AccessControlType == AccessControlType.Deny )
                {
                    switch ( modification )
                    { 
                        case AccessControlModification.Add :
                            _securityDescriptor.DiscretionaryAcl.AddAccess( AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags ); 
                            break; 

                        case AccessControlModification.Set : 
                            _securityDescriptor.DiscretionaryAcl.SetAccess( AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break;

                        case AccessControlModification.Reset : 
                            _securityDescriptor.DiscretionaryAcl.RemoveAccess( AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 0 );
                            _securityDescriptor.DiscretionaryAcl.SetAccess( AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags ); 
                            break; 

                        case AccessControlModification.Remove : 
                            result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                            break;

                        case AccessControlModification.RemoveAll : 
                            result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 0 );
                            if ( result == false ) 
                            { 
                                BCLDebug.Assert( false, "Invalid operation" );
                                throw new SystemException(); 
                            }

                            break;
 
                        case AccessControlModification.RemoveSpecific :
                            _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific( AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags ); 
                            break; 

                        default : 
                            throw new ArgumentOutOfRangeException(
                                "modification",
                                Environment.GetResourceString( "ArgumentOutOfRange_Enum" ));
                    } 
                }
                else 
                { 
                    BCLDebug.Assert( false, "rule.AccessControlType unrecognized" );
                    throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)rule.AccessControlType), "rule.AccessControlType" ); 
                }

                modified = result;
                AccessRulesModified |= modified; 
                return result;
            } 
            finally 
            {
                WriteUnlock(); 
            }
        }

        // 
        // Modifies the SACL
        // 
 
        protected override bool ModifyAudit( AccessControlModification modification, AuditRule rule, out bool modified )
        { 
            WriteLock();
            try
            {
                bool result = true; 

                if ( rule == null ) 
                { 
                    throw new ArgumentNullException( "rule" );
                } 

                if ( _securityDescriptor.SystemAcl == null )
                {
                    if ( modification == AccessControlModification.Remove || 
                        modification == AccessControlModification.RemoveAll ||
                        modification == AccessControlModification.RemoveSpecific ) 
                    { 
                        modified = false;
                        return result; 
                    }

                    _securityDescriptor.SystemAcl = new SystemAcl( IsContainer, IsDS, GenericAcl.AclRevision, 1 );
                    _securityDescriptor.AddControlFlags(ControlFlags.SystemAclPresent); 
                }
 
                SecurityIdentifier sid = rule.IdentityReference.Translate( typeof( SecurityIdentifier )) as SecurityIdentifier; 

                switch ( modification ) 
                {
                    case AccessControlModification.Add :
                        _securityDescriptor.SystemAcl.AddAudit( rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                        break; 

                    case AccessControlModification.Set : 
                        _securityDescriptor.SystemAcl.SetAudit( rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags ); 
                        break;
 
                    case AccessControlModification.Reset :
                        _securityDescriptor.SystemAcl.SetAudit( rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                        break;
 
                    case AccessControlModification.Remove :
                        result = _securityDescriptor.SystemAcl.RemoveAudit( rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags ); 
                        break; 

                    case AccessControlModification.RemoveAll : 
                        result = _securityDescriptor.SystemAcl.RemoveAudit( AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, 0 );
                        if ( result == false )
                        {
                            throw new InvalidProgramException(); 
                        }
 
                        break; 

                    case AccessControlModification.RemoveSpecific : 
                        _securityDescriptor.SystemAcl.RemoveAuditSpecific(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags );
                        break;

                    default : 
                        throw new ArgumentOutOfRangeException(
                            "modification", 
                            Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); 
                }
 
                modified = result;
                AuditRulesModified |= modified;
                return result;
            } 
            finally
            { 
                WriteUnlock(); 
            }
        } 

        #endregion

        #region Protected Methods 

        #endregion 
 
        #region Public Methods
 
        protected void AddAccessRule( AccessRule rule )
        {
            if ( rule == null )
            { 
                throw new ArgumentNullException("rule");
            } 
 
            WriteLock();
 
            try
            {
                bool modified;
                ModifyAccess( AccessControlModification.Add, rule, out modified ); 
            }
            finally 
            { 
                WriteUnlock();
            } 
        }

        protected void SetAccessRule( AccessRule rule )
        { 
            if ( rule == null )
            { 
                throw new ArgumentNullException("rule"); 
            }
 
            WriteLock();

            try
            { 
                bool modified;
                ModifyAccess( AccessControlModification.Set, rule, out modified ); 
            } 
            finally
            { 
                WriteUnlock();
            }
        }
 
        protected void ResetAccessRule( AccessRule rule )
        { 
            if ( rule == null ) 
            {
                throw new ArgumentNullException("rule"); 
            }

            WriteLock();
 
            try
            { 
                bool modified; 
                ModifyAccess( AccessControlModification.Reset, rule, out modified );
            } 
            finally
            {
                WriteUnlock();
            } 

            return; 
        } 

        protected bool RemoveAccessRule(AccessRule rule) 
        {
            if ( rule == null )
            {
                throw new ArgumentNullException( "rule" ); 
            }
 
            WriteLock(); 

            try 
            {
                if ( _securityDescriptor == null )
                {
                    return true; 
                }
 
                bool modified; 
                return ModifyAccess( AccessControlModification.Remove, rule, out modified );
            } 
            finally
            {
                WriteUnlock();
            } 
        }
 
        protected void RemoveAccessRuleAll( AccessRule rule ) 
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException("rule");
            }
 
            WriteLock();
 
            try 
            {
                if ( _securityDescriptor == null ) 
                {
                    return;
                }
 
                bool modified;
                ModifyAccess( AccessControlModification.RemoveAll, rule, out modified ); 
            } 
            finally
            { 
                WriteUnlock();
            }

            return; 
        }
 
        protected void RemoveAccessRuleSpecific( AccessRule rule ) 
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException("rule");
            }
 
            WriteLock();
 
            try 
            {
                if ( _securityDescriptor == null ) 
                {
                    return;
                }
 
                bool modified;
                ModifyAccess( AccessControlModification.RemoveSpecific, rule, out modified ); 
            } 
            finally
            { 
                WriteUnlock();
            }
        }
 
        protected void AddAuditRule( AuditRule rule )
        { 
            if ( rule == null ) 
            {
                throw new ArgumentNullException( "rule" ); 
            }

            WriteLock();
 
            try
            { 
                bool modified; 
                ModifyAudit( AccessControlModification.Add, rule, out modified );
            } 
            finally
            {
                WriteUnlock();
            } 
        }
 
        protected void SetAuditRule( AuditRule rule ) 
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException( "rule" );
            }
 
            WriteLock();
 
            try 
            {
                bool modified; 
                ModifyAudit( AccessControlModification.Set, rule, out modified );
            }
            finally
            { 
                WriteUnlock();
            } 
        } 

        protected bool RemoveAuditRule( AuditRule rule ) 
        {
            if ( rule == null )
            {
                throw new ArgumentNullException( "rule" ); 
            }
 
            WriteLock(); 

            try 
            {
                bool modified;
                return ModifyAudit( AccessControlModification.Remove, rule, out modified );
            } 
            finally
            { 
                WriteUnlock(); 
            }
        } 

        protected void RemoveAuditRuleAll( AuditRule rule )
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException( "rule" ); 
            } 

            WriteLock(); 

            try
            {
                bool modified; 
                ModifyAudit( AccessControlModification.RemoveAll, rule, out modified );
            } 
            finally 
            {
                WriteUnlock(); 
            }
        }

        protected void RemoveAuditRuleSpecific( AuditRule rule ) 
        {
            if ( rule == null ) 
            { 
                throw new ArgumentNullException( "rule" );
            } 

            WriteLock();

            try 
            {
                bool modified; 
                ModifyAudit( AccessControlModification.RemoveSpecific, rule, out modified ); 
            }
            finally 
            {
                WriteUnlock();
            }
        } 

        public AuthorizationRuleCollection GetAccessRules( bool includeExplicit, bool includeInherited, System.Type targetType ) 
        { 
            return GetRules( true, includeExplicit, includeInherited, targetType );
        } 

        public AuthorizationRuleCollection GetAuditRules( bool includeExplicit, bool includeInherited, System.Type targetType )
        {
            return GetRules( false, includeExplicit, includeInherited, targetType ); 
        }
 
        #endregion 
    }
} 


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK