Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / AccessControl / DirectoryObjectSecurity.cs / 1305376 / DirectoryObjectSecurity.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Classes: DirectoryObjectSecurity class ** ** ===========================================================*/ using Microsoft.Win32; using System; using System.Collections; using System.Security.Principal; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; namespace System.Security.AccessControl { public abstract class DirectoryObjectSecurity: ObjectSecurity { #region Constructors protected DirectoryObjectSecurity() : base(true, true) { return; } protected DirectoryObjectSecurity(CommonSecurityDescriptor securityDescriptor) : base(securityDescriptor) { return; } #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. // QualifiedAce ace = acl[i] as QualifiedAce; if (ace == null) { // // Only consider qualified ACEs // continue; } if (ace.IsCallback == true) { // // Ignore callback ACEs // continue; } if (access) { if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied) { continue; } } else { if (ace.AceQualifier != AceQualifier.SystemAudit) { continue; } } irSource.Add( ace.SecurityIdentifier ); } irTarget = irSource.Translate(targetType); } 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. // QualifiedAce ace = acl[i] as CommonAce; if (ace == null) { ace = acl[i] as ObjectAce; if (ace == null) { // // Only consider common or object ACEs // continue; } } if (ace.IsCallback == true) { // // Ignore callback ACEs // continue; } if (access) { if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied) { continue; } } else { if (ace.AceQualifier != AceQualifier.SystemAudit) { continue; } } if ((includeExplicit && ((ace.AceFlags & AceFlags.Inherited) == 0)) || (includeInherited && ((ace.AceFlags & AceFlags.Inherited) != 0))) { IdentityReference iref = (targetType == typeof(SecurityIdentifier )) ? ace.SecurityIdentifier : irTarget[i]; if (access) { AccessControlType type; if (ace.AceQualifier == AceQualifier.AccessAllowed) { type = AccessControlType.Allow; } else { type = AccessControlType.Deny; } if (ace is ObjectAce) { ObjectAce objectAce = ace as ObjectAce; result.AddRule(AccessRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, type, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = ace as CommonAce; if (commonAce == null) { continue; } result.AddRule(AccessRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, type)); } } else { if (ace is ObjectAce) { ObjectAce objectAce = ace as ObjectAce; result.AddRule(AuditRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, objectAce.AuditFlags, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = ace as CommonAce; if (commonAce == null) { continue; } result.AddRule(AuditRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, commonAce.AuditFlags)); } } } } return result; } finally { ReadUnlock(); } } // // Modifies the DACL // private bool ModifyAccess(AccessControlModification modification, ObjectAccessRule rule, out bool modified) { 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.AclRevisionDS, 1); _securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset ) && ( rule.ObjectFlags != ObjectAceFlags.None )) { // // This will result in an object ace being added to the dacl, so the dacl revision must be AclRevisionDS // if ( _securityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS ) { // // we need to create a new dacl with the same aces as the existing one but the revision should be AclRevisionDS // byte[] binaryForm = new byte[_securityDescriptor.DiscretionaryAcl.BinaryLength]; _securityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form _securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; default : throw new ArgumentOutOfRangeException( "modification", Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); } } else { Contract.Assert(false, "rule.AccessControlType unrecognized"); throw new SystemException(); } modified = result; AccessRulesModified |= modified; return result; } // // Modifies the SACL // private bool ModifyAudit(AccessControlModification modification, ObjectAuditRule rule, out bool modified) { 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.AclRevisionDS, 1); _securityDescriptor.AddControlFlags(ControlFlags.SystemAclPresent); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset ) && ( rule.ObjectFlags != ObjectAceFlags.None )) { // // This will result in an object ace being added to the sacl, so the sacl revision must be AclRevisionDS // if ( _securityDescriptor.SystemAcl.Revision < GenericAcl.AclRevisionDS ) { // // we need to create a new sacl with the same aces as the existing one but the revision should be AclRevisionDS // byte[] binaryForm = new byte[_securityDescriptor.SystemAcl.BinaryLength]; _securityDescriptor.SystemAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form _securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.SystemAcl.RemoveAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) { Contract.Assert(false, "Invalid operation"); throw new SystemException(); } break; case AccessControlModification.RemoveSpecific : _securityDescriptor.SystemAcl.RemoveAuditSpecific(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; default : throw new ArgumentOutOfRangeException( "modification", Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); } modified = result; AuditRulesModified |= modified; return result; } #endregion #region public Methods public virtual AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType) { throw new NotImplementedException(); } public virtual AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags, Guid objectType, Guid inheritedObjectType) { throw new NotImplementedException(); } protected override bool ModifyAccess(AccessControlModification modification, AccessRule rule, out bool modified) { if ( !this.AccessRuleType.IsAssignableFrom(rule.GetType()) ) { throw new ArgumentException( Environment.GetResourceString("AccessControl_InvalidAccessRuleType"), "rule"); } Contract.EndContractBlock(); return ModifyAccess(modification, rule as ObjectAccessRule, out modified); } protected override bool ModifyAudit(AccessControlModification modification, AuditRule rule, out bool modified) { if ( !this.AuditRuleType.IsAssignableFrom(rule.GetType()) ) { throw new ArgumentException( Environment.GetResourceString("AccessControl_InvalidAuditRuleType"), "rule"); } Contract.EndContractBlock(); return ModifyAudit(modification, rule as ObjectAuditRule, out modified); } #endregion #region Public Methods protected void AddAccessRule(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.Add, rule, out modified); } finally { WriteUnlock(); } return; } protected void SetAccessRule(ObjectAccessRule 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(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.Reset, rule, out modified); } finally { WriteUnlock(); } } protected bool RemoveAccessRule(ObjectAccessRule 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(ObjectAccessRule 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(); } } protected void RemoveAccessRuleSpecific(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); if (_securityDescriptor == null) { return; } WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.RemoveSpecific, rule, out modified); } finally { WriteUnlock(); } } protected void AddAuditRule(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Classes: DirectoryObjectSecurity class ** ** ===========================================================*/ using Microsoft.Win32; using System; using System.Collections; using System.Security.Principal; using System.Runtime.InteropServices; using System.Diagnostics.Contracts; namespace System.Security.AccessControl { public abstract class DirectoryObjectSecurity: ObjectSecurity { #region Constructors protected DirectoryObjectSecurity() : base(true, true) { return; } protected DirectoryObjectSecurity(CommonSecurityDescriptor securityDescriptor) : base(securityDescriptor) { return; } #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. // QualifiedAce ace = acl[i] as QualifiedAce; if (ace == null) { // // Only consider qualified ACEs // continue; } if (ace.IsCallback == true) { // // Ignore callback ACEs // continue; } if (access) { if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied) { continue; } } else { if (ace.AceQualifier != AceQualifier.SystemAudit) { continue; } } irSource.Add( ace.SecurityIdentifier ); } irTarget = irSource.Translate(targetType); } 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. // QualifiedAce ace = acl[i] as CommonAce; if (ace == null) { ace = acl[i] as ObjectAce; if (ace == null) { // // Only consider common or object ACEs // continue; } } if (ace.IsCallback == true) { // // Ignore callback ACEs // continue; } if (access) { if (ace.AceQualifier != AceQualifier.AccessAllowed && ace.AceQualifier != AceQualifier.AccessDenied) { continue; } } else { if (ace.AceQualifier != AceQualifier.SystemAudit) { continue; } } if ((includeExplicit && ((ace.AceFlags & AceFlags.Inherited) == 0)) || (includeInherited && ((ace.AceFlags & AceFlags.Inherited) != 0))) { IdentityReference iref = (targetType == typeof(SecurityIdentifier )) ? ace.SecurityIdentifier : irTarget[i]; if (access) { AccessControlType type; if (ace.AceQualifier == AceQualifier.AccessAllowed) { type = AccessControlType.Allow; } else { type = AccessControlType.Deny; } if (ace is ObjectAce) { ObjectAce objectAce = ace as ObjectAce; result.AddRule(AccessRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, type, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = ace as CommonAce; if (commonAce == null) { continue; } result.AddRule(AccessRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, type)); } } else { if (ace is ObjectAce) { ObjectAce objectAce = ace as ObjectAce; result.AddRule(AuditRuleFactory(iref, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, objectAce.AuditFlags, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = ace as CommonAce; if (commonAce == null) { continue; } result.AddRule(AuditRuleFactory(iref, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, commonAce.AuditFlags)); } } } } return result; } finally { ReadUnlock(); } } // // Modifies the DACL // private bool ModifyAccess(AccessControlModification modification, ObjectAccessRule rule, out bool modified) { 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.AclRevisionDS, 1); _securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset ) && ( rule.ObjectFlags != ObjectAceFlags.None )) { // // This will result in an object ace being added to the dacl, so the dacl revision must be AclRevisionDS // if ( _securityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS ) { // // we need to create a new dacl with the same aces as the existing one but the revision should be AclRevisionDS // byte[] binaryForm = new byte[_securityDescriptor.DiscretionaryAcl.BinaryLength]; _securityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form _securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; default : throw new ArgumentOutOfRangeException( "modification", Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); } } else { Contract.Assert(false, "rule.AccessControlType unrecognized"); throw new SystemException(); } modified = result; AccessRulesModified |= modified; return result; } // // Modifies the SACL // private bool ModifyAudit(AccessControlModification modification, ObjectAuditRule rule, out bool modified) { 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.AclRevisionDS, 1); _securityDescriptor.AddControlFlags(ControlFlags.SystemAclPresent); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset ) && ( rule.ObjectFlags != ObjectAceFlags.None )) { // // This will result in an object ace being added to the sacl, so the sacl revision must be AclRevisionDS // if ( _securityDescriptor.SystemAcl.Revision < GenericAcl.AclRevisionDS ) { // // we need to create a new sacl with the same aces as the existing one but the revision should be AclRevisionDS // byte[] binaryForm = new byte[_securityDescriptor.SystemAcl.BinaryLength]; _securityDescriptor.SystemAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form _securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } 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, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Set : _securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Reset : _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); _securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.Remove : result = _securityDescriptor.SystemAcl.RemoveAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; case AccessControlModification.RemoveAll : result = _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) { Contract.Assert(false, "Invalid operation"); throw new SystemException(); } break; case AccessControlModification.RemoveSpecific : _securityDescriptor.SystemAcl.RemoveAuditSpecific(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); break; default : throw new ArgumentOutOfRangeException( "modification", Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); } modified = result; AuditRulesModified |= modified; return result; } #endregion #region public Methods public virtual AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType) { throw new NotImplementedException(); } public virtual AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags, Guid objectType, Guid inheritedObjectType) { throw new NotImplementedException(); } protected override bool ModifyAccess(AccessControlModification modification, AccessRule rule, out bool modified) { if ( !this.AccessRuleType.IsAssignableFrom(rule.GetType()) ) { throw new ArgumentException( Environment.GetResourceString("AccessControl_InvalidAccessRuleType"), "rule"); } Contract.EndContractBlock(); return ModifyAccess(modification, rule as ObjectAccessRule, out modified); } protected override bool ModifyAudit(AccessControlModification modification, AuditRule rule, out bool modified) { if ( !this.AuditRuleType.IsAssignableFrom(rule.GetType()) ) { throw new ArgumentException( Environment.GetResourceString("AccessControl_InvalidAuditRuleType"), "rule"); } Contract.EndContractBlock(); return ModifyAudit(modification, rule as ObjectAuditRule, out modified); } #endregion #region Public Methods protected void AddAccessRule(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.Add, rule, out modified); } finally { WriteUnlock(); } return; } protected void SetAccessRule(ObjectAccessRule 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(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.Reset, rule, out modified); } finally { WriteUnlock(); } } protected bool RemoveAccessRule(ObjectAccessRule 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(ObjectAccessRule 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(); } } protected void RemoveAccessRuleSpecific(ObjectAccessRule rule) { if (rule == null) { throw new ArgumentNullException("rule"); } Contract.EndContractBlock(); if (_securityDescriptor == null) { return; } WriteLock(); try { bool modified; ModifyAccess(AccessControlModification.RemoveSpecific, rule, out modified); } finally { WriteUnlock(); } } protected void AddAuditRule(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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(ObjectAuditRule 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Int16Converter.cs
- GridEntry.cs
- Control.cs
- DatePickerTextBox.cs
- DocumentReferenceCollection.cs
- SourceElementsCollection.cs
- TemplateNameScope.cs
- RadioButtonList.cs
- ListBindableAttribute.cs
- MatrixTransform.cs
- OleDbParameterCollection.cs
- GPRECT.cs
- SiteMap.cs
- TypeInformation.cs
- ConfigurationSettings.cs
- TrackingDataItemValue.cs
- RowBinding.cs
- UIElementParagraph.cs
- X509CertificateTrustedIssuerElement.cs
- XmlAutoDetectWriter.cs
- ExtensionWindowHeader.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- BooleanFunctions.cs
- EntitySetBaseCollection.cs
- MenuRendererClassic.cs
- AnnotationHighlightLayer.cs
- EarlyBoundInfo.cs
- CommandValueSerializer.cs
- XmlSchemaAll.cs
- CryptoApi.cs
- WebPartDescriptionCollection.cs
- SvcMapFile.cs
- SdlChannelSink.cs
- DmlSqlGenerator.cs
- MouseButtonEventArgs.cs
- XamlTypeWithExplicitNamespace.cs
- ViewStateException.cs
- MimeMapping.cs
- SystemWebSectionGroup.cs
- CodeAccessPermission.cs
- MetadataSerializer.cs
- BindingExpression.cs
- WrappedIUnknown.cs
- DefaultAsyncDataDispatcher.cs
- UnionExpr.cs
- SecurityUtils.cs
- ComMethodElementCollection.cs
- X509ChainElement.cs
- GrammarBuilderRuleRef.cs
- TextDecorationCollection.cs
- DragDeltaEventArgs.cs
- CookieParameter.cs
- Geometry3D.cs
- AppDomainUnloadedException.cs
- PathFigureCollection.cs
- StrokeNodeEnumerator.cs
- PassportAuthentication.cs
- DesignerDataConnection.cs
- AssignDesigner.xaml.cs
- relpropertyhelper.cs
- ListViewDeleteEventArgs.cs
- Variant.cs
- MdiWindowListItemConverter.cs
- exports.cs
- VisualCollection.cs
- GACMembershipCondition.cs
- DetailsViewModeEventArgs.cs
- SqlTypeSystemProvider.cs
- ResourcePool.cs
- InternalCache.cs
- Pen.cs
- TimeSpanConverter.cs
- RangeBaseAutomationPeer.cs
- CubicEase.cs
- ThemeableAttribute.cs
- RowParagraph.cs
- Button.cs
- HWStack.cs
- TimeSpanStorage.cs
- AspNetSynchronizationContext.cs
- MarkupExtensionReturnTypeAttribute.cs
- TypeTypeConverter.cs
- DiscoveryDocumentLinksPattern.cs
- SplayTreeNode.cs
- IpcClientChannel.cs
- TransformGroup.cs
- ManipulationDevice.cs
- Directory.cs
- WeakKeyDictionary.cs
- MergablePropertyAttribute.cs
- DeploymentSectionCache.cs
- MulticastIPAddressInformationCollection.cs
- RootNamespaceAttribute.cs
- PolyLineSegment.cs
- DependencyObject.cs
- CoreSwitches.cs
- ConfigurationPropertyAttribute.cs
- DataGridViewRowPostPaintEventArgs.cs
- TableLayout.cs
- SynchronizedPool.cs