CommonObjectSecurity.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / AccessControl / CommonObjectSecurity.cs / 1305376 / 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;
using System.Diagnostics.Contracts; 

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)
        { 
            if (rule == null) 
            {
                throw new ArgumentNullException("rule"); 
            }
            Contract.EndContractBlock();

            WriteLock(); 
            try
            { 
                bool result = true; 

                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 )
                            { 
                                Contract.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 )
                            { 
                                Contract.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
                { 
                    Contract.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 )
        {
            if (rule == null)
            { 
                throw new ArgumentNullException("rule");
            } 
            Contract.EndContractBlock(); 

            WriteLock(); 
            try
            {
                bool result = true;
 
                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");
            } 
            Contract.EndContractBlock();

            WriteLock();
 
            try
            { 
                bool modified; 
                ModifyAccess( AccessControlModification.Add, rule, out modified );
            } 
            finally
            {
                WriteUnlock();
            } 
        }
 
        protected void SetAccessRule( AccessRule rule ) 
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException("rule");
            }
            Contract.EndContractBlock(); 

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

            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" );
            }
            Contract.EndContractBlock();
 
            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"); 
            }
            Contract.EndContractBlock();

            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");
            }
            Contract.EndContractBlock();
 
            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" ); 
            }
            Contract.EndContractBlock();

            WriteLock(); 

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

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

        protected bool RemoveAuditRule( AuditRule rule )
        {
            if ( rule == null ) 
            {
                throw new ArgumentNullException( "rule" ); 
            } 
            Contract.EndContractBlock();
 
            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" ); 
            }
            Contract.EndContractBlock();

            WriteLock(); 

            try 
            { 
                bool modified;
                ModifyAudit( AccessControlModification.RemoveAll, rule, out modified ); 
            }
            finally
            {
                WriteUnlock(); 
            }
        } 
 
        protected void RemoveAuditRuleSpecific( AuditRule rule )
        { 
            if ( rule == null )
            {
                throw new ArgumentNullException( "rule" );
            } 
            Contract.EndContractBlock();
 
            WriteLock(); 

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

        [System.Security.SecuritySafeCritical]  // auto-generated
        public AuthorizationRuleCollection GetAccessRules( bool includeExplicit, bool includeInherited, System.Type targetType )
        { 
            return GetRules( true, includeExplicit, includeInherited, targetType );
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public AuthorizationRuleCollection GetAuditRules( bool includeExplicit, bool includeInherited, System.Type targetType ) 
        {
            return GetRules( false, includeExplicit, includeInherited, targetType );
        }
 
        #endregion
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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