/// <summary>初始化 <see cref="T:System.Security.AccessControl.ObjectAce" /> 类的新实例。</summary> /// <param name="aceFlags">新的访问控制项 (ACE) 的继承、继承传播和审核条件。</param> /// <param name="qualifier">使用新的 ACE。</param> /// <param name="accessMask">ACE 的访问掩码。</param> /// <param name="sid">与新的 ACE 关联的 <see cref="T:System.Security.Principal.SecurityIdentifier" />。</param> /// <param name="flags"> /// <paramref name="type" /> 和 <paramref name="inheritedType" /> 参数是否包含有效的对象 GUID。</param> /// <param name="type">一个 GUID,标识新的 ACE 所应用到的对象类型。</param> /// <param name="inheritedType">一个 GUID,标识能够继承新的 ACE 的对象类型。</param> /// <param name="isCallback">如果新的 ACE 是回调类型的 ACE,则为 true。</param> /// <param name="opaque">与新的 ACE 关联的不透明数据。只有回调 ACE 类型才允许不透明数据。此数组的长度一定不能大于 <see cref="M:System.Security.AccessControl.ObjectAceMaxOpaqueLength" /> 方法的返回值。</param> /// <exception cref="T:System.ArgumentOutOfRangeException">qualifier 参数包含无效的值,或者不透明参数的值的长度大于 <see cref="M:System.Security.AccessControl.ObjectAceMaxOpaqueLength" /> 方法的返回值。</exception> public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base(ObjectAce.TypeFromQualifier(isCallback, qualifier), aceFlags, accessMask, sid, opaque) { this._objectFlags = flags; this._objectAceType = type; this._inheritedObjectAceType = inheritedType; }
static void GetObjectAceTypeGuids(ObjectAce ace, out Guid type, out Guid inheritedType) { type = Guid.Empty; inheritedType = Guid.Empty; if (0 != (ace.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent)) { type = ace.ObjectAceType; } if (0 != (ace.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent)) { inheritedType = ace.InheritedObjectAceType; } }
internal override AuditRule InternalAuditRuleFactory(QualifiedAce ace, Type targetType) { ObjectAce oace = ace as ObjectAce; if (null == oace || ObjectAceFlags.None == oace.ObjectAceFlags) { return(base.InternalAuditRuleFactory(ace, targetType)); } return(AuditRuleFactory(ace.SecurityIdentifier.Translate(targetType), ace.AccessMask, ace.IsInherited, ace.InheritanceFlags, ace.PropagationFlags, ace.AuditFlags, oace.ObjectAceType, oace.InheritedObjectAceType)); }
private void GetObjectTypesForSplit(ObjectAce originalAce, int accessMask, AceFlags aceFlags, out ObjectAceFlags objectFlags, out Guid objectType, out Guid inheritedObjectType) { objectFlags = ObjectAceFlags.None; objectType = Guid.Empty; inheritedObjectType = Guid.Empty; if ((accessMask & ObjectAce.AccessMaskWithObjectType) != 0) { objectType = originalAce.ObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent; } if (((byte)(aceFlags & AceFlags.ContainerInherit)) != 0) { inheritedObjectType = originalAce.InheritedObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent; } }
internal void AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { GenericAce ace; if (sid == null) { throw new ArgumentNullException("sid"); } this.ThrowIfNotCanonical(); bool flag = false; if ((qualifier == AceQualifier.SystemAudit) && (((byte)(flags & AceFlags.AuditFlags)) == 0)) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags"); } if (accessMask == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask"); } if (!this.IsDS || (objectFlags == ObjectAceFlags.None)) { ace = new CommonAce(flags, qualifier, accessMask, sid, false, null); } else { ace = new ObjectAce(flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, false, null); } if (this.InspectAce(ref ace, this is DiscretionaryAcl)) { for (int i = 0; i < this.Count; i++) { QualifiedAce ace2 = this._acl[i] as QualifiedAce; if ((ace2 != null) && this.MergeAces(ref ace2, ace as QualifiedAce)) { flag = true; break; } } if (!flag) { this._acl.InsertAce(this._acl.Count, ace); this._isDirty = true; } this.OnAclModificationTried(); } }
internal void RemoveQualifiedAcesSpecific(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { if (accessMask == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask"); } if ((qualifier == AceQualifier.SystemAudit) && (((byte)(flags & AceFlags.AuditFlags)) == 0)) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags"); } if (sid == null) { throw new ArgumentNullException("sid"); } this.ThrowIfNotCanonical(); for (int i = 0; i < this.Count; i++) { QualifiedAce ace = this._acl[i] as QualifiedAce; if ((((ace == null) || (((byte)(ace.AceFlags & AceFlags.Inherited)) != 0)) || ((ace.AceQualifier != qualifier) || (ace.SecurityIdentifier != sid))) || ((ace.AceFlags != flags) || (ace.AccessMask != accessMask))) { continue; } if (this.IsDS) { if ((ace is ObjectAce) && (objectFlags != ObjectAceFlags.None)) { ObjectAce ace2 = ace as ObjectAce; if (ace2.ObjectTypesMatch(objectFlags, objectType) && ace2.InheritedObjectTypesMatch(objectFlags, inheritedObjectType)) { goto Label_00F2; } continue; } if ((ace is ObjectAce) || (objectFlags != ObjectAceFlags.None)) { continue; } } Label_00F2: this._acl.RemoveAce(i); i--; } this.OnAclModificationTried(); }
private bool GetAccessMaskForRemoval(QualifiedAce ace, ObjectAceFlags objectFlags, Guid objectType, ref int accessMask) { if (((ace.AccessMask & accessMask) & ObjectAce.AccessMaskWithObjectType) != 0) { if (ace is ObjectAce) { ObjectAce ace2 = ace as ObjectAce; if (((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None) && ((ace2.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)) { return(false); } if (!(((objectFlags & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None) || ace2.ObjectTypesMatch(objectFlags, objectType))) { accessMask &= ~ObjectAce.AccessMaskWithObjectType; } } else if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None) { return(false); } } return(true); }
private bool GetInheritanceFlagsForRemoval(QualifiedAce ace, ObjectAceFlags objectFlags, Guid inheritedObjectType, ref AceFlags aceFlags) { if ((((byte)(ace.AceFlags & AceFlags.ContainerInherit)) != 0) && (((byte)(aceFlags & AceFlags.ContainerInherit)) != 0)) { if (ace is ObjectAce) { ObjectAce ace2 = ace as ObjectAce; if (((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != ObjectAceFlags.None) && ((ace2.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent) == ObjectAceFlags.None)) { return(false); } if (!(((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) == ObjectAceFlags.None) || ace2.InheritedObjectTypesMatch(objectFlags, inheritedObjectType))) { aceFlags = (AceFlags)((byte)(((int)aceFlags) & 240)); } } else if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != ObjectAceFlags.None) { return(false); } } return(true); }
/// <summary>Creates a <see cref="T:System.Security.AccessControl.GenericAce" /> object from the specified binary data.</summary> /// <param name="binaryForm">The binary data from which to create the new <see cref="T:System.Security.AccessControl.GenericAce" /> object.</param> /// <param name="offset">The offset at which to begin unmarshaling.</param> /// <returns>The <see cref="T:System.Security.AccessControl.GenericAce" /> object this method creates.</returns> // Token: 0x06001E46 RID: 7750 RVA: 0x00069C80 File Offset: 0x00067E80 public static GenericAce CreateFromBinaryForm(byte[] binaryForm, int offset) { GenericAce.VerifyHeader(binaryForm, offset); AceType aceType = (AceType)binaryForm[offset]; GenericAce genericAce; if (aceType == AceType.AccessAllowed || aceType == AceType.AccessDenied || aceType == AceType.SystemAudit || aceType == AceType.SystemAlarm || aceType == AceType.AccessAllowedCallback || aceType == AceType.AccessDeniedCallback || aceType == AceType.SystemAuditCallback || aceType == AceType.SystemAlarmCallback) { AceQualifier qualifier; int accessMask; SecurityIdentifier sid; bool isCallback; byte[] opaque; if (!CommonAce.ParseBinaryForm(binaryForm, offset, out qualifier, out accessMask, out sid, out isCallback, out opaque)) { goto IL_1A8; } AceFlags flags = (AceFlags)binaryForm[offset + 1]; genericAce = new CommonAce(flags, qualifier, accessMask, sid, isCallback, opaque); } else if (aceType == AceType.AccessAllowedObject || aceType == AceType.AccessDeniedObject || aceType == AceType.SystemAuditObject || aceType == AceType.SystemAlarmObject || aceType == AceType.AccessAllowedCallbackObject || aceType == AceType.AccessDeniedCallbackObject || aceType == AceType.SystemAuditCallbackObject || aceType == AceType.SystemAlarmCallbackObject) { AceQualifier qualifier2; int accessMask2; SecurityIdentifier sid2; ObjectAceFlags flags2; Guid type; Guid inheritedType; bool isCallback2; byte[] opaque2; if (!ObjectAce.ParseBinaryForm(binaryForm, offset, out qualifier2, out accessMask2, out sid2, out flags2, out type, out inheritedType, out isCallback2, out opaque2)) { goto IL_1A8; } AceFlags aceFlags = (AceFlags)binaryForm[offset + 1]; genericAce = new ObjectAce(aceFlags, qualifier2, accessMask2, sid2, flags2, type, inheritedType, isCallback2, opaque2); } else if (aceType == AceType.AccessAllowedCompound) { int accessMask3; CompoundAceType compoundAceType; SecurityIdentifier sid3; if (!CompoundAce.ParseBinaryForm(binaryForm, offset, out accessMask3, out compoundAceType, out sid3)) { goto IL_1A8; } AceFlags flags3 = (AceFlags)binaryForm[offset + 1]; genericAce = new CompoundAce(flags3, accessMask3, compoundAceType, sid3); } else { AceFlags flags4 = (AceFlags)binaryForm[offset + 1]; byte[] array = null; int num = (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8); if (num % 4 != 0) { goto IL_1A8; } int num2 = num - 4; if (num2 > 0) { array = new byte[num2]; for (int i = 0; i < num2; i++) { array[i] = binaryForm[offset + num - num2 + i]; } } genericAce = new CustomAce(aceType, flags4, array); } if ((genericAce is ObjectAce || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) == genericAce.BinaryLength) && (!(genericAce is ObjectAce) || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) == genericAce.BinaryLength || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) - 32 == genericAce.BinaryLength)) { return(genericAce); } IL_1A8: throw new ArgumentException(Environment.GetResourceString("ArgumentException_InvalidAceBinaryForm"), "binaryForm"); }
public static GenericAce CreateFromBinaryForm(byte[] binaryForm, int offset) { GenericAce ace; VerifyHeader(binaryForm, offset); System.Security.AccessControl.AceType type = (System.Security.AccessControl.AceType)binaryForm[offset]; switch (type) { case System.Security.AccessControl.AceType.AccessAllowed: case System.Security.AccessControl.AceType.AccessDenied: case System.Security.AccessControl.AceType.SystemAudit: case System.Security.AccessControl.AceType.SystemAlarm: case System.Security.AccessControl.AceType.AccessAllowedCallback: case System.Security.AccessControl.AceType.AccessDeniedCallback: case System.Security.AccessControl.AceType.SystemAuditCallback: case System.Security.AccessControl.AceType.SystemAlarmCallback: { AceQualifier qualifier; int num; SecurityIdentifier identifier; bool flag; byte[] buffer; if (!CommonAce.ParseBinaryForm(binaryForm, offset, out qualifier, out num, out identifier, out flag, out buffer)) { goto Label_01A8; } System.Security.AccessControl.AceFlags flags = (System.Security.AccessControl.AceFlags)binaryForm[offset + 1]; ace = new CommonAce(flags, qualifier, num, identifier, flag, buffer); break; } case System.Security.AccessControl.AceType.AccessAllowedObject: case System.Security.AccessControl.AceType.AccessDeniedObject: case System.Security.AccessControl.AceType.SystemAuditObject: case System.Security.AccessControl.AceType.SystemAlarmObject: case System.Security.AccessControl.AceType.AccessAllowedCallbackObject: case System.Security.AccessControl.AceType.AccessDeniedCallbackObject: case System.Security.AccessControl.AceType.SystemAuditCallbackObject: case System.Security.AccessControl.AceType.SystemAlarmCallbackObject: { AceQualifier qualifier2; int num2; SecurityIdentifier identifier2; ObjectAceFlags flags2; Guid guid; Guid guid2; bool flag2; byte[] buffer2; if (!ObjectAce.ParseBinaryForm(binaryForm, offset, out qualifier2, out num2, out identifier2, out flags2, out guid, out guid2, out flag2, out buffer2)) { goto Label_01A8; } System.Security.AccessControl.AceFlags aceFlags = (System.Security.AccessControl.AceFlags)binaryForm[offset + 1]; ace = new ObjectAce(aceFlags, qualifier2, num2, identifier2, flags2, guid, guid2, flag2, buffer2); break; } case System.Security.AccessControl.AceType.AccessAllowedCompound: { int num3; CompoundAceType type2; SecurityIdentifier identifier3; if (!CompoundAce.ParseBinaryForm(binaryForm, offset, out num3, out type2, out identifier3)) { goto Label_01A8; } System.Security.AccessControl.AceFlags flags4 = (System.Security.AccessControl.AceFlags)binaryForm[offset + 1]; ace = new CompoundAce(flags4, num3, type2, identifier3); break; } default: { System.Security.AccessControl.AceFlags flags5 = (System.Security.AccessControl.AceFlags)binaryForm[offset + 1]; byte[] opaque = null; int num4 = binaryForm[offset + 2] + (binaryForm[offset + 3] << 8); if ((num4 % 4) != 0) { goto Label_01A8; } int num5 = num4 - 4; if (num5 > 0) { opaque = new byte[num5]; for (int i = 0; i < num5; i++) { opaque[i] = binaryForm[((offset + num4) - num5) + i]; } } ace = new CustomAce(type, flags5, opaque); break; } } if (((ace is ObjectAce) || ((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) == ace.BinaryLength)) && ((!(ace is ObjectAce) || ((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) == ace.BinaryLength)) || (((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) - 0x20) == ace.BinaryLength))) { return(ace); } Label_01A8: throw new ArgumentException(Environment.GetResourceString("ArgumentException_InvalidAceBinaryForm"), "binaryForm"); }
private AuthorizationRuleCollection GetRules(bool access, bool includeExplicit, bool includeInherited, System.Type targetType) { ReadLock(); try { AuthorizationRuleCollection result = new AuthorizationRuleCollection(); if (!IsValidTargetTypeStatic(targetType)) { throw new ArgumentException(SR.Arg_MustBeIdentityReferenceType, nameof(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(); } }
internal bool RemoveQualifiedAces(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, bool saclSemantics, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { if (accessMask == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask"); } if ((qualifier == AceQualifier.SystemAudit) && (((byte) (flags & AceFlags.AuditFlags)) == 0)) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags"); } if (sid == null) { throw new ArgumentNullException("sid"); } this.ThrowIfNotCanonical(); bool flag = true; bool flag2 = true; int num = accessMask; AceFlags flags2 = flags; byte[] binaryForm = new byte[this.BinaryLength]; this.GetBinaryForm(binaryForm, 0); Label_0075: try { for (int i = 0; i < this.Count; i++) { QualifiedAce ace = this._acl[i] as QualifiedAce; if (((ace == null) || (((byte) (ace.AceFlags & AceFlags.Inherited)) != 0)) || ((ace.AceQualifier != qualifier) || (ace.SecurityIdentifier != sid))) { continue; } if (this.IsDS) { accessMask = num; bool flag3 = !this.GetAccessMaskForRemoval(ace, objectFlags, objectType, ref accessMask); if ((ace.AccessMask & accessMask) == 0) { continue; } flags = flags2; bool flag4 = !this.GetInheritanceFlagsForRemoval(ace, objectFlags, inheritedObjectType, ref flags); if (((((((byte) (ace.AceFlags & AceFlags.ContainerInherit)) == 0) && (((byte) (flags & AceFlags.ContainerInherit)) != 0)) && (((byte) (flags & AceFlags.InheritOnly)) != 0)) || (((((byte) (flags & AceFlags.ContainerInherit)) == 0) && (((byte) (ace.AceFlags & AceFlags.ContainerInherit)) != 0)) && (((byte) (ace.AceFlags & AceFlags.InheritOnly)) != 0))) || (((((byte) (flags2 & AceFlags.ContainerInherit)) != 0) && (((byte) (flags2 & AceFlags.InheritOnly)) != 0)) && (((byte) (flags & AceFlags.ContainerInherit)) == 0))) { continue; } if (!flag3 && !flag4) { goto Label_0184; } flag2 = false; goto Label_0483; } if ((ace.AccessMask & accessMask) == 0) { continue; } Label_0184: if (!saclSemantics || (((byte) (((byte) (ace.AceFlags & flags)) & 0xc0)) != 0)) { AceFlags none = AceFlags.None; int num3 = 0; ObjectAceFlags flags4 = ObjectAceFlags.None; Guid empty = Guid.Empty; Guid guid2 = Guid.Empty; AceFlags aceFlags = AceFlags.None; int num4 = 0; ObjectAceFlags flags6 = ObjectAceFlags.None; Guid guid3 = Guid.Empty; Guid guid4 = Guid.Empty; AceFlags existing = AceFlags.None; int num5 = 0; ObjectAceFlags flags8 = ObjectAceFlags.None; Guid guid5 = Guid.Empty; Guid guid6 = Guid.Empty; AceFlags result = AceFlags.None; bool total = false; none = ace.AceFlags; num3 = ace.AccessMask & ~accessMask; if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num3, none, out flags4, out empty, out guid2); } if (saclSemantics) { aceFlags = (AceFlags) ((byte) (ace.AceFlags & ~((byte) (flags & AceFlags.AuditFlags)))); num4 = ace.AccessMask & accessMask; if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num4, aceFlags, out flags6, out guid3, out guid4); } } existing = (AceFlags) ((byte) (((byte) (ace.AceFlags & (AceFlags.ContainerInherit | AceFlags.InheritOnly | AceFlags.NoPropagateInherit | AceFlags.ObjectInherit))) | ((byte) (((byte) (flags & ace.AceFlags)) & 0xc0)))); num5 = ace.AccessMask & accessMask; if (!saclSemantics || (((byte) (existing & AceFlags.AuditFlags)) != 0)) { if (!RemoveInheritanceBits(existing, flags, this.IsDS, out result, out total)) { flag2 = false; goto Label_0483; } if (!total) { result = (AceFlags) ((byte) (result | ((byte) (existing & AceFlags.AuditFlags)))); if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num5, result, out flags8, out guid5, out guid6); } } } if (!flag) { QualifiedAce ace2; if (num3 != 0) { if (((ace is ObjectAce) && ((((ObjectAce) ace).ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None)) && ((flags4 & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)) { this._acl.RemoveAce(i); ObjectAce ace3 = new ObjectAce(none, qualifier, num3, ace.SecurityIdentifier, flags4, empty, guid2, false, null); this._acl.InsertAce(i, ace3); } else { ace.AceFlags = none; ace.AccessMask = num3; if (ace is ObjectAce) { ObjectAce ace4 = ace as ObjectAce; ace4.ObjectAceFlags = flags4; ace4.ObjectAceType = empty; ace4.InheritedObjectAceType = guid2; } } } else { this._acl.RemoveAce(i); i--; } if (saclSemantics && (((byte) (aceFlags & AceFlags.AuditFlags)) != 0)) { if (ace is CommonAce) { ace2 = new CommonAce(aceFlags, qualifier, num4, ace.SecurityIdentifier, false, null); } else { ace2 = new ObjectAce(aceFlags, qualifier, num4, ace.SecurityIdentifier, flags6, guid3, guid4, false, null); } i++; this._acl.InsertAce(i, ace2); } if (!total) { if (ace is CommonAce) { ace2 = new CommonAce(result, qualifier, num5, ace.SecurityIdentifier, false, null); } else { ace2 = new ObjectAce(result, qualifier, num5, ace.SecurityIdentifier, flags8, guid5, guid6, false, null); } i++; this._acl.InsertAce(i, ace2); } } } } } catch (OverflowException) { this._acl.SetBinaryForm(binaryForm, 0); return false; } Label_0483: if (flag && flag2) { flag = false; goto Label_0075; } this.OnAclModificationTried(); return flag2; }
internal bool RemoveQualifiedAces(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, bool saclSemantics, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { if (accessMask == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask"); } if ((qualifier == AceQualifier.SystemAudit) && (((byte)(flags & AceFlags.AuditFlags)) == 0)) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags"); } if (sid == null) { throw new ArgumentNullException("sid"); } this.ThrowIfNotCanonical(); bool flag = true; bool flag2 = true; int num = accessMask; AceFlags flags2 = flags; byte[] binaryForm = new byte[this.BinaryLength]; this.GetBinaryForm(binaryForm, 0); Label_0075: try { for (int i = 0; i < this.Count; i++) { QualifiedAce ace = this._acl[i] as QualifiedAce; if (((ace == null) || (((byte)(ace.AceFlags & AceFlags.Inherited)) != 0)) || ((ace.AceQualifier != qualifier) || (ace.SecurityIdentifier != sid))) { continue; } if (this.IsDS) { accessMask = num; bool flag3 = !this.GetAccessMaskForRemoval(ace, objectFlags, objectType, ref accessMask); if ((ace.AccessMask & accessMask) == 0) { continue; } flags = flags2; bool flag4 = !this.GetInheritanceFlagsForRemoval(ace, objectFlags, inheritedObjectType, ref flags); if (((((((byte)(ace.AceFlags & AceFlags.ContainerInherit)) == 0) && (((byte)(flags & AceFlags.ContainerInherit)) != 0)) && (((byte)(flags & AceFlags.InheritOnly)) != 0)) || (((((byte)(flags & AceFlags.ContainerInherit)) == 0) && (((byte)(ace.AceFlags & AceFlags.ContainerInherit)) != 0)) && (((byte)(ace.AceFlags & AceFlags.InheritOnly)) != 0))) || (((((byte)(flags2 & AceFlags.ContainerInherit)) != 0) && (((byte)(flags2 & AceFlags.InheritOnly)) != 0)) && (((byte)(flags & AceFlags.ContainerInherit)) == 0))) { continue; } if (!flag3 && !flag4) { goto Label_0184; } flag2 = false; goto Label_0483; } if ((ace.AccessMask & accessMask) == 0) { continue; } Label_0184: if (!saclSemantics || (((byte)(((byte)(ace.AceFlags & flags)) & 0xc0)) != 0)) { AceFlags none = AceFlags.None; int num3 = 0; ObjectAceFlags flags4 = ObjectAceFlags.None; Guid empty = Guid.Empty; Guid guid2 = Guid.Empty; AceFlags aceFlags = AceFlags.None; int num4 = 0; ObjectAceFlags flags6 = ObjectAceFlags.None; Guid guid3 = Guid.Empty; Guid guid4 = Guid.Empty; AceFlags existing = AceFlags.None; int num5 = 0; ObjectAceFlags flags8 = ObjectAceFlags.None; Guid guid5 = Guid.Empty; Guid guid6 = Guid.Empty; AceFlags result = AceFlags.None; bool total = false; none = ace.AceFlags; num3 = ace.AccessMask & ~accessMask; if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num3, none, out flags4, out empty, out guid2); } if (saclSemantics) { aceFlags = (AceFlags)((byte)(ace.AceFlags & ~((byte)(flags & AceFlags.AuditFlags)))); num4 = ace.AccessMask & accessMask; if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num4, aceFlags, out flags6, out guid3, out guid4); } } existing = (AceFlags)((byte)(((byte)(ace.AceFlags & (AceFlags.ContainerInherit | AceFlags.InheritOnly | AceFlags.NoPropagateInherit | AceFlags.ObjectInherit))) | ((byte)(((byte)(flags & ace.AceFlags)) & 0xc0)))); num5 = ace.AccessMask & accessMask; if (!saclSemantics || (((byte)(existing & AceFlags.AuditFlags)) != 0)) { if (!RemoveInheritanceBits(existing, flags, this.IsDS, out result, out total)) { flag2 = false; goto Label_0483; } if (!total) { result = (AceFlags)((byte)(result | ((byte)(existing & AceFlags.AuditFlags)))); if (ace is ObjectAce) { this.GetObjectTypesForSplit(ace as ObjectAce, num5, result, out flags8, out guid5, out guid6); } } } if (!flag) { QualifiedAce ace2; if (num3 != 0) { if (((ace is ObjectAce) && ((((ObjectAce)ace).ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None)) && ((flags4 & ObjectAceFlags.ObjectAceTypePresent) == ObjectAceFlags.None)) { this._acl.RemoveAce(i); ObjectAce ace3 = new ObjectAce(none, qualifier, num3, ace.SecurityIdentifier, flags4, empty, guid2, false, null); this._acl.InsertAce(i, ace3); } else { ace.AceFlags = none; ace.AccessMask = num3; if (ace is ObjectAce) { ObjectAce ace4 = ace as ObjectAce; ace4.ObjectAceFlags = flags4; ace4.ObjectAceType = empty; ace4.InheritedObjectAceType = guid2; } } } else { this._acl.RemoveAce(i); i--; } if (saclSemantics && (((byte)(aceFlags & AceFlags.AuditFlags)) != 0)) { if (ace is CommonAce) { ace2 = new CommonAce(aceFlags, qualifier, num4, ace.SecurityIdentifier, false, null); } else { ace2 = new ObjectAce(aceFlags, qualifier, num4, ace.SecurityIdentifier, flags6, guid3, guid4, false, null); } i++; this._acl.InsertAce(i, ace2); } if (!total) { if (ace is CommonAce) { ace2 = new CommonAce(result, qualifier, num5, ace.SecurityIdentifier, false, null); } else { ace2 = new ObjectAce(result, qualifier, num5, ace.SecurityIdentifier, flags8, guid5, guid6, false, null); } i++; this._acl.InsertAce(i, ace2); } } } } } catch (OverflowException) { this._acl.SetBinaryForm(binaryForm, 0); return(false); } Label_0483: if (flag && flag2) { flag = false; goto Label_0075; } this.OnAclModificationTried(); return(flag2); }
private AuthorizationRuleCollection GetRules(bool access, bool includeExplicit, bool includeInherited, Type targetType) { AuthorizationRuleCollection rules2; base.ReadLock(); try { AuthorizationRuleCollection rules = new AuthorizationRuleCollection(); if (!SecurityIdentifier.IsValidTargetTypeStatic(targetType)) { throw new ArgumentException(Environment.GetResourceString("Arg_MustBeIdentityReferenceType"), "targetType"); } CommonAcl discretionaryAcl = null; if (access) { if ((base._securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != ControlFlags.None) { discretionaryAcl = base._securityDescriptor.DiscretionaryAcl; } } else if ((base._securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != ControlFlags.None) { discretionaryAcl = base._securityDescriptor.SystemAcl; } if (discretionaryAcl == null) { return(rules); } IdentityReferenceCollection references = null; if (targetType != typeof(SecurityIdentifier)) { IdentityReferenceCollection references2 = new IdentityReferenceCollection(discretionaryAcl.Count); for (int j = 0; j < discretionaryAcl.Count; j++) { QualifiedAce ace = discretionaryAcl[j] as QualifiedAce; if ((ace == null) || ace.IsCallback) { continue; } if (access) { if ((ace.AceQualifier == AceQualifier.AccessAllowed) || (ace.AceQualifier == AceQualifier.AccessDenied)) { goto Label_00DD; } continue; } if (ace.AceQualifier != AceQualifier.SystemAudit) { continue; } Label_00DD: references2.Add(ace.SecurityIdentifier); } references = references2.Translate(targetType); } for (int i = 0; i < discretionaryAcl.Count; i++) { QualifiedAce ace2 = discretionaryAcl[i] as CommonAce; if (ace2 == null) { ace2 = discretionaryAcl[i] as ObjectAce; if (ace2 == null) { continue; } } if (ace2.IsCallback) { continue; } if (access) { if ((ace2.AceQualifier == AceQualifier.AccessAllowed) || (ace2.AceQualifier == AceQualifier.AccessDenied)) { goto Label_0174; } continue; } if (ace2.AceQualifier != AceQualifier.SystemAudit) { continue; } Label_0174: if ((includeExplicit && (((byte)(ace2.AceFlags & AceFlags.Inherited)) == 0)) || (includeInherited && (((byte)(ace2.AceFlags & AceFlags.Inherited)) != 0))) { IdentityReference identityReference = (targetType == typeof(SecurityIdentifier)) ? ace2.SecurityIdentifier : references[i]; if (access) { AccessControlType allow; if (ace2.AceQualifier == AceQualifier.AccessAllowed) { allow = AccessControlType.Allow; } else { allow = AccessControlType.Deny; } if (ace2 is ObjectAce) { ObjectAce ace3 = ace2 as ObjectAce; rules.AddRule(this.AccessRuleFactory(identityReference, ace3.AccessMask, ace3.IsInherited, ace3.InheritanceFlags, ace3.PropagationFlags, allow, ace3.ObjectAceType, ace3.InheritedObjectAceType)); } else { CommonAce ace4 = ace2 as CommonAce; if (ace4 != null) { rules.AddRule(this.AccessRuleFactory(identityReference, ace4.AccessMask, ace4.IsInherited, ace4.InheritanceFlags, ace4.PropagationFlags, allow)); } } } else if (ace2 is ObjectAce) { ObjectAce ace5 = ace2 as ObjectAce; rules.AddRule(this.AuditRuleFactory(identityReference, ace5.AccessMask, ace5.IsInherited, ace5.InheritanceFlags, ace5.PropagationFlags, ace5.AuditFlags, ace5.ObjectAceType, ace5.InheritedObjectAceType)); } else { CommonAce ace6 = ace2 as CommonAce; if (ace6 != null) { rules.AddRule(this.AuditRuleFactory(identityReference, ace6.AccessMask, ace6.IsInherited, ace6.InheritanceFlags, ace6.PropagationFlags, ace6.AuditFlags)); } } } } rules2 = rules; } finally { base.ReadUnlock(); } return(rules2); }
// // This method determines whether the object type and inherited object type from the original ace // should be retained or not based on access mask and aceflags for a given split // private void GetObjectTypesForSplit( ObjectAce originalAce, int accessMask, AceFlags aceFlags, out ObjectAceFlags objectFlags, out Guid objectType, out Guid inheritedObjectType ) { objectFlags = 0; objectType = Guid.Empty; inheritedObjectType = Guid.Empty; // // We should retain the object type if the access mask for this split contains any bits that refer to object type // if (( accessMask & ObjectAce.AccessMaskWithObjectType ) != 0 ) { // keep the original ace's object flags and object type objectType = originalAce.ObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent; } // // We should retain the inherited object type if the aceflags for this contains inheritance (ContainerInherit) // if (( aceFlags & AceFlags.ContainerInherit ) != 0 ) { // keep the original ace's object flags and object type inheritedObjectType = originalAce.InheritedObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent; } }
private void GetObjectTypesForSplit(ObjectAce originalAce, int accessMask, AceFlags aceFlags, out ObjectAceFlags objectFlags, out Guid objectType, out Guid inheritedObjectType) { objectFlags = ObjectAceFlags.None; objectType = Guid.Empty; inheritedObjectType = Guid.Empty; if ((accessMask & ObjectAce.AccessMaskWithObjectType) != 0) { objectType = originalAce.ObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent; } if (((byte) (aceFlags & AceFlags.ContainerInherit)) != 0) { inheritedObjectType = originalAce.InheritedObjectAceType; objectFlags |= originalAce.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent; } }
// // Helper function behind all the SetXXX methods // internal void SetQualifiedAce( SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType ) { if ( sid == null ) { throw new ArgumentNullException( "sid" ); } if ( qualifier == AceQualifier.SystemAudit && (( flags & AceFlags.AuditFlags ) == 0 )) { throw new ArgumentException( Environment.GetResourceString( "Arg_EnumAtLeastOneFlag" ), "flags" ); } if ( accessMask == 0 ) { throw new ArgumentException( Environment.GetResourceString( "Argument_ArgumentZero" ), "accessMask" ); } Contract.EndContractBlock(); ThrowIfNotCanonical(); GenericAce newAce; if (( !IsDS ) || ( objectFlags == ObjectAceFlags.None )) { newAce = new CommonAce( flags, qualifier, accessMask, sid, false, null ); } else { newAce = new ObjectAce( flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, false, null ); } // // Make sure the new ACE wouldn't be meaningless before proceeding // if ( false == InspectAce( ref newAce, ( this is DiscretionaryAcl ))) { return; } for ( int i = 0; i < Count; i++ ) { QualifiedAce ace = _acl[i] as QualifiedAce; // // Not a qualified ACE - keep going // if ( ace == null ) { continue; } // // Only interested in explicit (non-inherited) ACEs // if (( ace.AceFlags & AceFlags.Inherited ) != 0 ) { continue; } // // Only interested in ACEs with the specified qualifier // if ( ace.AceQualifier != qualifier ) { continue; } // // Only interested in ACEs with the specified SID // if ( ace.SecurityIdentifier != sid ) { continue; } // // This ACE corresponds to the SID and qualifier in question - remove it // _acl.RemoveAce( i ); i--; } // // As a final step, add the ACE we want. // Add it at the end - we'll re-canonicalize later. // _acl.InsertAce( _acl.Count, newAce ); // // To aid the efficiency of batch operations, recanonicalize this later // _isDirty = true; OnAclModificationTried(); }
/// <summary>从指定的二进制数据创建一个 <see cref="T:System.Security.AccessControl.GenericAce" /> 对象。</summary> /// <returns>此方法创建的 <see cref="T:System.Security.AccessControl.GenericAce" /> 对象。</returns> /// <param name="binaryForm">用于创建新 <see cref="T:System.Security.AccessControl.GenericAce" /> 对象的二进制数据。</param> /// <param name="offset">开始取消封送的偏移量。</param> public static GenericAce CreateFromBinaryForm(byte[] binaryForm, int offset) { GenericAce.VerifyHeader(binaryForm, offset); AceType type = (AceType)binaryForm[offset]; GenericAce genericAce; switch (type) { case AceType.AccessAllowed: case AceType.AccessDenied: case AceType.SystemAudit: case AceType.SystemAlarm: case AceType.AccessAllowedCallback: case AceType.AccessDeniedCallback: case AceType.SystemAuditCallback: case AceType.SystemAlarmCallback: AceQualifier qualifier1; int accessMask1; SecurityIdentifier sid1; bool isCallback1; byte[] opaque1; if (CommonAce.ParseBinaryForm(binaryForm, offset, out qualifier1, out accessMask1, out sid1, out isCallback1, out opaque1)) { genericAce = (GenericAce) new CommonAce((AceFlags)binaryForm[offset + 1], qualifier1, accessMask1, sid1, isCallback1, opaque1); break; } goto label_15; case AceType.AccessAllowedObject: case AceType.AccessDeniedObject: case AceType.SystemAuditObject: case AceType.SystemAlarmObject: case AceType.AccessAllowedCallbackObject: case AceType.AccessDeniedCallbackObject: case AceType.SystemAuditCallbackObject: case AceType.SystemAlarmCallbackObject: AceQualifier qualifier2; int accessMask2; SecurityIdentifier sid2; ObjectAceFlags objectFlags; Guid objectAceType; Guid inheritedObjectAceType; bool isCallback2; byte[] opaque2; if (ObjectAce.ParseBinaryForm(binaryForm, offset, out qualifier2, out accessMask2, out sid2, out objectFlags, out objectAceType, out inheritedObjectAceType, out isCallback2, out opaque2)) { genericAce = (GenericAce) new ObjectAce((AceFlags)binaryForm[offset + 1], qualifier2, accessMask2, sid2, objectFlags, objectAceType, inheritedObjectAceType, isCallback2, opaque2); break; } goto label_15; case AceType.AccessAllowedCompound: int accessMask3; CompoundAceType compoundAceType; SecurityIdentifier sid3; if (CompoundAce.ParseBinaryForm(binaryForm, offset, out accessMask3, out compoundAceType, out sid3)) { genericAce = (GenericAce) new CompoundAce((AceFlags)binaryForm[offset + 1], accessMask3, compoundAceType, sid3); break; } goto label_15; default: AceFlags flags = (AceFlags)binaryForm[offset + 1]; byte[] opaque3 = (byte[])null; int num = (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8); if (num % 4 == 0) { int length = num - 4; if (length > 0) { opaque3 = new byte[length]; for (int index = 0; index < length; ++index) { opaque3[index] = binaryForm[offset + num - length + index]; } } genericAce = (GenericAce) new CustomAce(type, flags, opaque3); break; } goto label_15; } if ((genericAce is ObjectAce || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) == genericAce.BinaryLength) && (!(genericAce is ObjectAce) || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) == genericAce.BinaryLength || (int)binaryForm[offset + 2] + ((int)binaryForm[offset + 3] << 8) - 32 == genericAce.BinaryLength)) { return(genericAce); } label_15: throw new ArgumentException(Environment.GetResourceString("ArgumentException_InvalidAceBinaryForm"), "binaryForm"); }
static void GetObjectAceTypeGuids(ObjectAce ace, out Guid type, out Guid inheritedType) { type = Guid.Empty; inheritedType = Guid.Empty; if (0 != (ace.ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent)) type = ace.ObjectAceType; if (0 != (ace.ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent)) inheritedType = ace.InheritedObjectAceType; }
GenericAce MergeExplicitAcePair(GenericAce ace1, GenericAce ace2) { QualifiedAce qace1 = ace1 as QualifiedAce; QualifiedAce qace2 = ace2 as QualifiedAce; if (!(null != qace1 && null != qace2)) { return(null); } if (!(qace1.AceQualifier == qace2.AceQualifier)) { return(null); } if (!(qace1.SecurityIdentifier == qace2.SecurityIdentifier)) { return(null); } AceFlags aceFlags1 = qace1.AceFlags, aceFlags2 = qace2.AceFlags, aceFlagsNew; int accessMask1 = qace1.AccessMask, accessMask2 = qace2.AccessMask, accessMaskNew; if (!IsContainer) { aceFlags1 &= ~AceFlags.InheritanceFlags; aceFlags2 &= ~AceFlags.InheritanceFlags; } if (aceFlags1 != aceFlags2) { if (accessMask1 != accessMask2) { return(null); } 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; } CommonAce cace1 = ace1 as CommonAce; CommonAce cace2 = ace2 as CommonAce; if (null != cace1 && null != cace2) { return(new CommonAce(aceFlagsNew, cace1.AceQualifier, accessMaskNew, cace1.SecurityIdentifier, cace1.IsCallback, cace1.GetOpaque())); } ObjectAce oace1 = ace1 as ObjectAce; ObjectAce oace2 = ace2 as ObjectAce; if (null != oace1 && null != oace2) { // See DiscretionaryAclTest.GuidEmptyMergesRegardlessOfFlagsAndOpaqueDataIsNotConsidered Guid type1, inheritedType1; GetObjectAceTypeGuids(oace1, out type1, out inheritedType1); Guid type2, inheritedType2; GetObjectAceTypeGuids(oace2, out type2, out inheritedType2); if (type1 == type2 && inheritedType1 == inheritedType2) { return(new ObjectAce(aceFlagsNew, oace1.AceQualifier, accessMaskNew, oace1.SecurityIdentifier, oace1.ObjectAceFlags, oace1.ObjectAceType, oace1.InheritedObjectAceType, oace1.IsCallback, oace1.GetOpaque())); } } return(null); }
private AuthorizationRuleCollection GetRules(bool access, bool includeExplicit, bool includeInherited, Type targetType) { this.ReadLock(); try { AuthorizationRuleCollection authorizationRuleCollection = new AuthorizationRuleCollection(); if (!SecurityIdentifier.IsValidTargetTypeStatic(targetType)) { throw new ArgumentException(Environment.GetResourceString("Arg_MustBeIdentityReferenceType"), "targetType"); } CommonAcl commonAcl = (CommonAcl)null; if (access) { if ((this._securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != ControlFlags.None) { commonAcl = (CommonAcl)this._securityDescriptor.DiscretionaryAcl; } } else if ((this._securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != ControlFlags.None) { commonAcl = (CommonAcl)this._securityDescriptor.SystemAcl; } if (commonAcl == null) { return(authorizationRuleCollection); } IdentityReferenceCollection referenceCollection1 = (IdentityReferenceCollection)null; if (targetType != typeof(SecurityIdentifier)) { IdentityReferenceCollection referenceCollection2 = new IdentityReferenceCollection(commonAcl.Count); for (int index = 0; index < commonAcl.Count; ++index) { QualifiedAce qualifiedAce = commonAcl[index] as QualifiedAce; if (!((GenericAce)qualifiedAce == (GenericAce)null) && !qualifiedAce.IsCallback) { if (access) { if (qualifiedAce.AceQualifier != AceQualifier.AccessAllowed && qualifiedAce.AceQualifier != AceQualifier.AccessDenied) { continue; } } else if (qualifiedAce.AceQualifier != AceQualifier.SystemAudit) { continue; } referenceCollection2.Add((IdentityReference)qualifiedAce.SecurityIdentifier); } } referenceCollection1 = referenceCollection2.Translate(targetType); } for (int index = 0; index < commonAcl.Count; ++index) { QualifiedAce qualifiedAce = (QualifiedAce)(commonAcl[index] as CommonAce); if ((GenericAce)qualifiedAce == (GenericAce)null) { qualifiedAce = (QualifiedAce)(commonAcl[index] as ObjectAce); if ((GenericAce)qualifiedAce == (GenericAce)null) { continue; } } if (!qualifiedAce.IsCallback) { if (access) { if (qualifiedAce.AceQualifier != AceQualifier.AccessAllowed && qualifiedAce.AceQualifier != AceQualifier.AccessDenied) { continue; } } else if (qualifiedAce.AceQualifier != AceQualifier.SystemAudit) { continue; } if (includeExplicit && (qualifiedAce.AceFlags & AceFlags.Inherited) == AceFlags.None || includeInherited && (qualifiedAce.AceFlags & AceFlags.Inherited) != AceFlags.None) { IdentityReference identityReference = targetType == typeof(SecurityIdentifier) ? (IdentityReference)qualifiedAce.SecurityIdentifier : referenceCollection1[index]; if (access) { AccessControlType type = qualifiedAce.AceQualifier != AceQualifier.AccessAllowed ? AccessControlType.Deny : AccessControlType.Allow; if (qualifiedAce is ObjectAce) { ObjectAce objectAce = qualifiedAce as ObjectAce; authorizationRuleCollection.AddRule((AuthorizationRule)this.AccessRuleFactory(identityReference, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, type, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = qualifiedAce as CommonAce; if (!((GenericAce)commonAce == (GenericAce)null)) { authorizationRuleCollection.AddRule((AuthorizationRule)this.AccessRuleFactory(identityReference, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, type)); } } } else if (qualifiedAce is ObjectAce) { ObjectAce objectAce = qualifiedAce as ObjectAce; authorizationRuleCollection.AddRule((AuthorizationRule)this.AuditRuleFactory(identityReference, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, objectAce.AuditFlags, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); } else { CommonAce commonAce = qualifiedAce as CommonAce; if (!((GenericAce)commonAce == (GenericAce)null)) { authorizationRuleCollection.AddRule((AuthorizationRule)this.AuditRuleFactory(identityReference, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, commonAce.AuditFlags)); } } } } } return(authorizationRuleCollection); } finally { this.ReadUnlock(); } }
// // Instantiates the most-derived ACE type based on the binary // representation of an ACE // public static GenericAce CreateFromBinaryForm(byte[] binaryForm, int offset) { GenericAce result; AceType type; // // Sanity check the header // VerifyHeader(binaryForm, offset); type = (AceType)binaryForm[offset]; if (type == AceType.AccessAllowed || type == AceType.AccessDenied || type == AceType.SystemAudit || type == AceType.SystemAlarm || type == AceType.AccessAllowedCallback || type == AceType.AccessDeniedCallback || type == AceType.SystemAuditCallback || type == AceType.SystemAlarmCallback) { AceQualifier qualifier; int accessMask; SecurityIdentifier sid; bool isCallback; byte[] opaque; if (true == CommonAce.ParseBinaryForm(binaryForm, offset, out qualifier, out accessMask, out sid, out isCallback, out opaque)) { AceFlags flags = (AceFlags)binaryForm[offset + 1]; result = new CommonAce(flags, qualifier, accessMask, sid, isCallback, opaque); } else { goto InvalidParameter; } } else if (type == AceType.AccessAllowedObject || type == AceType.AccessDeniedObject || type == AceType.SystemAuditObject || type == AceType.SystemAlarmObject || type == AceType.AccessAllowedCallbackObject || type == AceType.AccessDeniedCallbackObject || type == AceType.SystemAuditCallbackObject || type == AceType.SystemAlarmCallbackObject) { AceQualifier qualifier; int accessMask; SecurityIdentifier sid; ObjectAceFlags objectFlags; Guid objectAceType; Guid inheritedObjectAceType; bool isCallback; byte[] opaque; if (true == ObjectAce.ParseBinaryForm(binaryForm, offset, out qualifier, out accessMask, out sid, out objectFlags, out objectAceType, out inheritedObjectAceType, out isCallback, out opaque)) { AceFlags flags = (AceFlags)binaryForm[offset + 1]; result = new ObjectAce(flags, qualifier, accessMask, sid, objectFlags, objectAceType, inheritedObjectAceType, isCallback, opaque); } else { goto InvalidParameter; } } else if (type == AceType.AccessAllowedCompound) { int accessMask; CompoundAceType compoundAceType; SecurityIdentifier sid; if (true == CompoundAce.ParseBinaryForm(binaryForm, offset, out accessMask, out compoundAceType, out sid)) { AceFlags flags = (AceFlags)binaryForm[offset + 1]; result = new CompoundAce(flags, accessMask, compoundAceType, sid); } else { goto InvalidParameter; } } else { AceFlags flags = (AceFlags)binaryForm[offset + 1]; byte[] opaque = null; int aceLength = (binaryForm[offset + 2] << 0) + (binaryForm[offset + 3] << 8); if (aceLength % 4 != 0) { goto InvalidParameter; } int opaqueLength = aceLength - HeaderLength; if (opaqueLength > 0) { opaque = new byte[opaqueLength]; for (int i = 0; i < opaqueLength; i++) { opaque[i] = binaryForm[offset + aceLength - opaqueLength + i]; } } result = new CustomAce(type, flags, opaque); } // // As a final check, confirm that the advertised ACE header length // was the actual parsed length // if (((!(result is ObjectAce)) && ((binaryForm[offset + 2] << 0) + (binaryForm[offset + 3] << 8) != result.BinaryLength)) // // This is needed because object aces created through ADSI have the advertised ACE length // greater than the actual length by 32 (bug in ADSI). // || ((result is ObjectAce) && ((binaryForm[offset + 2] << 0) + (binaryForm[offset + 3] << 8) != result.BinaryLength) && (((binaryForm[offset + 2] << 0) + (binaryForm[offset + 3] << 8) - 32) != result.BinaryLength))) { goto InvalidParameter; } return result; InvalidParameter: throw new ArgumentException( SR.ArgumentException_InvalidAceBinaryForm, nameof(binaryForm)); }
public void GetBinaryForm () { RawSecurityDescriptor sd = new RawSecurityDescriptor (""); sd.Owner = new SecurityIdentifier (WellKnownSidType.BuiltinUsersSid, null); sd.Group = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null); sd.DiscretionaryAcl = new RawAcl (1, 0); sd.SystemAcl = new RawAcl (1, 0); sd.SetFlags (sd.ControlFlags | ControlFlags.DiscretionaryAclPresent | ControlFlags.SystemAclPresent); // Empty ACL form byte[] buffer = new byte[sd.BinaryLength]; sd.GetBinaryForm (buffer, 0); byte[] sdBinary = new byte[] { 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }; Assert.AreEqual (sdBinary, buffer); // Add an ACE to the DACL SecurityIdentifier builtInAdmins = new SecurityIdentifier (WellKnownSidType.BuiltinAdministratorsSid, null); CommonAce ace = new CommonAce (AceFlags.None, AceQualifier.AccessAllowed, 0x7FFFFFFF, builtInAdmins, false, null); sd.DiscretionaryAcl.InsertAce (0, ace); buffer = new byte[sd.BinaryLength]; sd.GetBinaryForm (buffer, 0); sdBinary = new byte[] { 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0x7F, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 }; Assert.AreEqual (sdBinary, buffer); // This time with an Object ACE ObjectAce objectAce = new ObjectAce (AceFlags.Inherited, AceQualifier.AccessAllowed, 0x12345678, builtInAdmins, ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent, new Guid ("189c0dc7-b849-4dea-93a5-6d4cb8857a5c"), new Guid ("53b4a3d4-fe39-468b-bc60-b4fcba772fa5"), false, null); sd.DiscretionaryAcl = new RawAcl (2, 0); sd.DiscretionaryAcl.InsertAce (0, objectAce); buffer = new byte[sd.BinaryLength]; sd.GetBinaryForm (buffer, 0); sdBinary = new byte[] { 0x01, 0x00, 0x14, 0x80, 0x14, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x44, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x10, 0x3C, 0x00, 0x78, 0x56, 0x34, 0x12, 0x03, 0x00, 0x00, 0x00, 0xC7, 0x0D, 0x9C, 0x18, 0x49, 0xB8, 0xEA, 0x4D, 0x93, 0xA5, 0x6D, 0x4C, 0xB8, 0x85, 0x7A, 0x5C, 0xD4, 0xA3, 0xB4, 0x53, 0x39, 0xFE, 0x8B, 0x46, 0xBC, 0x60, 0xB4, 0xFC, 0xBA, 0x77, 0x2F, 0xA5, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 }; Assert.AreEqual (sdBinary, buffer); }
public static GenericAce CreateFromBinaryForm(byte[] binaryForm, int offset) { GenericAce ace; VerifyHeader(binaryForm, offset); System.Security.AccessControl.AceType type = (System.Security.AccessControl.AceType) binaryForm[offset]; switch (type) { case System.Security.AccessControl.AceType.AccessAllowed: case System.Security.AccessControl.AceType.AccessDenied: case System.Security.AccessControl.AceType.SystemAudit: case System.Security.AccessControl.AceType.SystemAlarm: case System.Security.AccessControl.AceType.AccessAllowedCallback: case System.Security.AccessControl.AceType.AccessDeniedCallback: case System.Security.AccessControl.AceType.SystemAuditCallback: case System.Security.AccessControl.AceType.SystemAlarmCallback: { AceQualifier qualifier; int num; SecurityIdentifier identifier; bool flag; byte[] buffer; if (!CommonAce.ParseBinaryForm(binaryForm, offset, out qualifier, out num, out identifier, out flag, out buffer)) { goto Label_01A8; } System.Security.AccessControl.AceFlags flags = (System.Security.AccessControl.AceFlags) binaryForm[offset + 1]; ace = new CommonAce(flags, qualifier, num, identifier, flag, buffer); break; } case System.Security.AccessControl.AceType.AccessAllowedObject: case System.Security.AccessControl.AceType.AccessDeniedObject: case System.Security.AccessControl.AceType.SystemAuditObject: case System.Security.AccessControl.AceType.SystemAlarmObject: case System.Security.AccessControl.AceType.AccessAllowedCallbackObject: case System.Security.AccessControl.AceType.AccessDeniedCallbackObject: case System.Security.AccessControl.AceType.SystemAuditCallbackObject: case System.Security.AccessControl.AceType.SystemAlarmCallbackObject: { AceQualifier qualifier2; int num2; SecurityIdentifier identifier2; ObjectAceFlags flags2; Guid guid; Guid guid2; bool flag2; byte[] buffer2; if (!ObjectAce.ParseBinaryForm(binaryForm, offset, out qualifier2, out num2, out identifier2, out flags2, out guid, out guid2, out flag2, out buffer2)) { goto Label_01A8; } System.Security.AccessControl.AceFlags aceFlags = (System.Security.AccessControl.AceFlags) binaryForm[offset + 1]; ace = new ObjectAce(aceFlags, qualifier2, num2, identifier2, flags2, guid, guid2, flag2, buffer2); break; } case System.Security.AccessControl.AceType.AccessAllowedCompound: { int num3; CompoundAceType type2; SecurityIdentifier identifier3; if (!CompoundAce.ParseBinaryForm(binaryForm, offset, out num3, out type2, out identifier3)) { goto Label_01A8; } System.Security.AccessControl.AceFlags flags4 = (System.Security.AccessControl.AceFlags) binaryForm[offset + 1]; ace = new CompoundAce(flags4, num3, type2, identifier3); break; } default: { System.Security.AccessControl.AceFlags flags5 = (System.Security.AccessControl.AceFlags) binaryForm[offset + 1]; byte[] opaque = null; int num4 = binaryForm[offset + 2] + (binaryForm[offset + 3] << 8); if ((num4 % 4) != 0) { goto Label_01A8; } int num5 = num4 - 4; if (num5 > 0) { opaque = new byte[num5]; for (int i = 0; i < num5; i++) { opaque[i] = binaryForm[((offset + num4) - num5) + i]; } } ace = new CustomAce(type, flags5, opaque); break; } } if (((ace is ObjectAce) || ((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) == ace.BinaryLength)) && ((!(ace is ObjectAce) || ((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) == ace.BinaryLength)) || (((binaryForm[offset + 2] + (binaryForm[offset + 3] << 8)) - 0x20) == ace.BinaryLength))) { return ace; } Label_01A8: throw new ArgumentException(Environment.GetResourceString("ArgumentException_InvalidAceBinaryForm"), "binaryForm"); }
// // Helper function behind all the AddXXX methods for qualified aces // internal void AddQualifiedAce( SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType ) { if ( sid == null ) { throw new ArgumentNullException( "sid" ); } Contract.EndContractBlock(); ThrowIfNotCanonical(); bool aceMerged = false; // if still false after all attempts to merge, create new entry if ( qualifier == AceQualifier.SystemAudit && (( flags & AceFlags.AuditFlags ) == 0 )) { throw new ArgumentException( Environment.GetResourceString( "Arg_EnumAtLeastOneFlag" ), "flags" ); } if ( accessMask == 0 ) { throw new ArgumentException( Environment.GetResourceString( "Argument_ArgumentZero" ), "accessMask" ); } GenericAce newAce; if (( !IsDS ) || ( objectFlags == ObjectAceFlags.None )) { newAce = new CommonAce( flags, qualifier, accessMask, sid, false, null ); } else { newAce = new ObjectAce( flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, false, null ); } // // Make sure the new ACE wouldn't be meaningless before proceeding // if ( false == InspectAce( ref newAce, ( this is DiscretionaryAcl ))) { return; } // // See if the new ACE can be merged with any of the existing ones // for ( int i = 0; i < Count; i++ ) { QualifiedAce ace = _acl[i] as QualifiedAce; if ( ace == null ) { continue; } if ( true == MergeAces( ref ace, newAce as QualifiedAce )) { aceMerged = true; break; } } // // Couldn't modify any existing entry, so add a new one // if ( !aceMerged ) { _acl.InsertAce( _acl.Count, newAce ); _isDirty = true; } OnAclModificationTried(); }
// Token: 0x06001FF6 RID: 8182 RVA: 0x0006FAEC File Offset: 0x0006DCEC private AuthorizationRuleCollection GetRules(bool access, bool includeExplicit, bool includeInherited, Type targetType) { base.ReadLock(); AuthorizationRuleCollection result; try { AuthorizationRuleCollection authorizationRuleCollection = new AuthorizationRuleCollection(); if (!SecurityIdentifier.IsValidTargetTypeStatic(targetType)) { throw new ArgumentException(Environment.GetResourceString("Arg_MustBeIdentityReferenceType"), "targetType"); } CommonAcl commonAcl = null; if (access) { if ((this._securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != ControlFlags.None) { commonAcl = this._securityDescriptor.DiscretionaryAcl; } } else if ((this._securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != ControlFlags.None) { commonAcl = this._securityDescriptor.SystemAcl; } if (commonAcl == null) { result = authorizationRuleCollection; } else { IdentityReferenceCollection identityReferenceCollection = null; if (targetType != typeof(SecurityIdentifier)) { IdentityReferenceCollection identityReferenceCollection2 = new IdentityReferenceCollection(commonAcl.Count); for (int i = 0; i < commonAcl.Count; i++) { QualifiedAce qualifiedAce = commonAcl[i] as QualifiedAce; if (!(qualifiedAce == null) && !qualifiedAce.IsCallback) { if (access) { if (qualifiedAce.AceQualifier != AceQualifier.AccessAllowed && qualifiedAce.AceQualifier != AceQualifier.AccessDenied) { goto IL_EB; } } else if (qualifiedAce.AceQualifier != AceQualifier.SystemAudit) { goto IL_EB; } identityReferenceCollection2.Add(qualifiedAce.SecurityIdentifier); } IL_EB :; } identityReferenceCollection = identityReferenceCollection2.Translate(targetType); } int j = 0; while (j < commonAcl.Count) { QualifiedAce qualifiedAce2 = commonAcl[j] as CommonAce; if (!(qualifiedAce2 == null)) { goto IL_142; } qualifiedAce2 = (commonAcl[j] as ObjectAce); if (!(qualifiedAce2 == null)) { goto IL_142; } IL_306: j++; continue; IL_142: if (qualifiedAce2.IsCallback) { goto IL_306; } if (access) { if (qualifiedAce2.AceQualifier != AceQualifier.AccessAllowed && qualifiedAce2.AceQualifier != AceQualifier.AccessDenied) { goto IL_306; } } else if (qualifiedAce2.AceQualifier != AceQualifier.SystemAudit) { goto IL_306; } if ((!includeExplicit || (qualifiedAce2.AceFlags & AceFlags.Inherited) != AceFlags.None) && (!includeInherited || (qualifiedAce2.AceFlags & AceFlags.Inherited) == AceFlags.None)) { goto IL_306; } IdentityReference identityReference = (targetType == typeof(SecurityIdentifier)) ? qualifiedAce2.SecurityIdentifier : identityReferenceCollection[j]; if (access) { AccessControlType type; if (qualifiedAce2.AceQualifier == AceQualifier.AccessAllowed) { type = AccessControlType.Allow; } else { type = AccessControlType.Deny; } if (qualifiedAce2 is ObjectAce) { ObjectAce objectAce = qualifiedAce2 as ObjectAce; authorizationRuleCollection.AddRule(this.AccessRuleFactory(identityReference, objectAce.AccessMask, objectAce.IsInherited, objectAce.InheritanceFlags, objectAce.PropagationFlags, type, objectAce.ObjectAceType, objectAce.InheritedObjectAceType)); goto IL_306; } CommonAce commonAce = qualifiedAce2 as CommonAce; if (!(commonAce == null)) { authorizationRuleCollection.AddRule(this.AccessRuleFactory(identityReference, commonAce.AccessMask, commonAce.IsInherited, commonAce.InheritanceFlags, commonAce.PropagationFlags, type)); goto IL_306; } goto IL_306; } else { if (qualifiedAce2 is ObjectAce) { ObjectAce objectAce2 = qualifiedAce2 as ObjectAce; authorizationRuleCollection.AddRule(this.AuditRuleFactory(identityReference, objectAce2.AccessMask, objectAce2.IsInherited, objectAce2.InheritanceFlags, objectAce2.PropagationFlags, objectAce2.AuditFlags, objectAce2.ObjectAceType, objectAce2.InheritedObjectAceType)); goto IL_306; } CommonAce commonAce2 = qualifiedAce2 as CommonAce; if (!(commonAce2 == null)) { authorizationRuleCollection.AddRule(this.AuditRuleFactory(identityReference, commonAce2.AccessMask, commonAce2.IsInherited, commonAce2.InheritanceFlags, commonAce2.PropagationFlags, commonAce2.AuditFlags)); goto IL_306; } goto IL_306; } } result = authorizationRuleCollection; } } finally { base.ReadUnlock(); } return(result); }
// // Helper function behind all the RemoveXXX methods // internal bool RemoveQualifiedAces( SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, bool saclSemantics, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType ) { if ( accessMask == 0 ) { throw new ArgumentException( Environment.GetResourceString( "Argument_ArgumentZero" ), "accessMask" ); } if ( qualifier == AceQualifier.SystemAudit && (( flags & AceFlags.AuditFlags ) == 0 )) { throw new ArgumentException( Environment.GetResourceString( "Arg_EnumAtLeastOneFlag" ), "flags" ); } if ( sid == null ) { throw new ArgumentNullException( "sid" ); } Contract.EndContractBlock(); ThrowIfNotCanonical(); // // Two passes are made. // During the first pass, no changes are made to the ACL, // the ACEs are simply evaluated to ascertain that the operation // can succeed. // If everything is kosher, the second pass is the one that makes changes. // bool evaluationPass = true; bool removePossible = true; // unless proven otherwise // // Needed for DS acls to keep track of the original access mask specified for removal // int originalAccessMask = accessMask; AceFlags originalFlags = flags; // // It is possible that the removal will result in an overflow exception // because more ACEs get inserted. // Save the current state of the object and revert to it later if // and exception is thrown. // byte[] recovery = new byte[BinaryLength]; GetBinaryForm( recovery, 0 ); MakeAnotherPass: try { for ( int i = 0; i < Count; i++ ) { QualifiedAce ace = _acl[i] as QualifiedAce; // // Not a qualified ACE - keep going // if ( ace == null ) { continue; } // // Only interested in explicit (non-inherited) ACEs // if (( ace.AceFlags & AceFlags.Inherited ) != 0 ) { continue; } // // Only interested in ACEs with the specified qualifier // if ( ace.AceQualifier != qualifier ) { continue; } // // Only interested in ACEs with the specified SID // if ( ace.SecurityIdentifier != sid ) { continue; } // // If access masks have nothing in common, skip the whole exercise // if ( IsDS ) { // // incase of directory aces, if the access mask of the // existing and new ace have any bits in common that need // an object type, then we need to perform some checks on the // object types in the two aces. Since certain bits are further qualified // by the object type they cannot be determined to be common without // inspecting the object type. It is possible that the same bits may be set but // the object types are different in which case they are really not common bits. // accessMask = originalAccessMask; bool objectTypesConflict = !GetAccessMaskForRemoval( ace, objectFlags, objectType, ref accessMask ); // if the access masks have nothing in common, skip if (( ace.AccessMask & accessMask ) == 0 ) { continue; } // // incase of directory aces, if the existing and new ace are being inherited, // then we need to perform some checks on the // inherited object types in the two aces. Since inheritance is further qualified // by the inherited object type the inheritance flags cannot be determined to be common without // inspecting the inherited object type. It is possible that both aces may be further inherited but if // the inherited object types are different the inheritance may not be common. // flags = originalFlags; bool inheritedObjectTypesConflict = !GetInheritanceFlagsForRemoval( ace, objectFlags, inheritedObjectType, ref flags ); if (((( ace.AceFlags & AceFlags.ContainerInherit ) == 0 ) && (( flags & AceFlags.ContainerInherit ) != 0 ) && (( flags & AceFlags.InheritOnly ) != 0 )) || ((( flags & AceFlags.ContainerInherit ) == 0 ) && (( ace.AceFlags & AceFlags.ContainerInherit ) != 0 ) && (( ace.AceFlags & AceFlags.InheritOnly ) != 0))) { // if one ace applies only to self and the other only to children/descendents we have nothing in common continue; } // // if the ace being removed referred only to child types and child types among existing ace and // ace being removed are not common then there is nothing in common between these aces (skip) // if ((( originalFlags & AceFlags.ContainerInherit ) != 0 ) && (( originalFlags & AceFlags.InheritOnly ) != 0 ) && (( flags & AceFlags.ContainerInherit ) == 0 )) { continue; } if ( objectTypesConflict || inheritedObjectTypesConflict ) { // // if we reached this stage, then we've found something common between the two aces. // But since there is a conflict between the object types (or inherited object types), the remove is not possible // removePossible = false; break; } } else { if (( ace.AccessMask & accessMask ) == 0 ) { continue; } } // // If audit flags on a SACL have nothing in common, // skip the whole exercise // if ( saclSemantics && (( ace.AceFlags & flags & AceFlags.AuditFlags ) == 0 )) { continue; } // // See if the ACE needs to be split into several // To illustrate with an example, consider this equation: // From: CI OI NP SA FA R W // Remove: OI IO NP SA R // // PermissionSplit: CI OI NP SA FA W // remove R // AuditingSplit: CI OI NP FA R // remove SA // MergeSplit: CI OI NP SA R // ready for merge // Remove: OI IO NP SA R // same audit and perm flags as merge split // // Result: CI OI NP SA FA W // PermissionSplit // CI OI NP FA R // AuditingSplit // CI NP SA R // Result of perm removal // // // Example for DS acls (when removal is possible) // // From: CI(Guid) LC CC(Guid) // Remove: CI IO LC // // PermissionSplit: CI(Guid) CC(Guid) // Remove GR // MergeSplit: CI(Guid) LC // Ready for merge // Remove: CI IO LC // Removal is possible since we are trying to remove inheritance for // all child types when it exists for one specific child type // // Result: CI(Guid) CC(Guid) // PermissionSplit // LC // Result of perm removal // // // Example for DS acls (when removal is NOT possible) // // From: CI GR CC(Guid) // Remove: CI(Guid) IO LC // // PermissionSplit: CI CC(Guid) // Remove GR // MergeSplit: CI LC // Ready for merge // Remove: CI(Guid) IO CC // Removal is not possible since we are trying to remove // inheritance for a specific child type when it exists for all child types // // Permission split settings AceFlags ps_AceFlags = 0; int ps_AccessMask = 0; ObjectAceFlags ps_ObjectAceFlags = 0; Guid ps_ObjectAceType = Guid.Empty; Guid ps_InheritedObjectAceType = Guid.Empty; // Auditing split makes sense if this is a SACL AceFlags as_AceFlags = 0; int as_AccessMask = 0; ObjectAceFlags as_ObjectAceFlags = 0; Guid as_ObjectAceType = Guid.Empty; Guid as_InheritedObjectAceType = Guid.Empty; // Merge split settings AceFlags ms_AceFlags = 0; int ms_AccessMask = 0; ObjectAceFlags ms_ObjectAceFlags = 0; Guid ms_ObjectAceType = Guid.Empty; Guid ms_InheritedObjectAceType = Guid.Empty; // Merge result settings AceFlags mergeResultFlags = 0; bool mergeRemoveTotal = false; // // First compute the permission split // ps_AceFlags = ace.AceFlags; unchecked { ps_AccessMask = ace.AccessMask & ~accessMask; } if ( ace is ObjectAce ) { // // determine what should be the object/inherited object types on the permission split // GetObjectTypesForSplit( ace as ObjectAce, ps_AccessMask /* access mask for this split */, ps_AceFlags /* flags remain the same */, out ps_ObjectAceFlags, out ps_ObjectAceType, out ps_InheritedObjectAceType ); } // // Next, for SACLs only, compute the auditing split // if ( saclSemantics ) { // // This operation can set the audit bits region // of ACE flags to zero; // This case will be handled later // unchecked { as_AceFlags = ace.AceFlags & ~( flags & AceFlags.AuditFlags ); } // // The result of this evaluation is guaranteed // not to be zero by now // as_AccessMask = ( ace.AccessMask & accessMask ); if ( ace is ObjectAce ) { // // determine what should be the object/inherited object types on the audit split // GetObjectTypesForSplit( ace as ObjectAce, as_AccessMask /* access mask for this split */, as_AceFlags /* flags remain the same for inheritance */, out as_ObjectAceFlags, out as_ObjectAceType, out as_InheritedObjectAceType ); } } // // Finally, compute the merge split // ms_AceFlags = ( ace.AceFlags & AceFlags.InheritanceFlags ) | ( flags & ace.AceFlags & AceFlags.AuditFlags ); ms_AccessMask = ( ace.AccessMask & accessMask ); // // Now is the time to obtain the result of applying the remove // operation to the merge split // Skipping this step for SACLs where the merge split step // produced no auditing flags // if ( !saclSemantics || (( ms_AceFlags & AceFlags.AuditFlags ) != 0 )) { if ( false == RemoveInheritanceBits( ms_AceFlags, flags, IsDS, out mergeResultFlags, out mergeRemoveTotal )) { removePossible = false; break; } if ( !mergeRemoveTotal ) { mergeResultFlags |= ( ms_AceFlags & AceFlags.AuditFlags ); if ( ace is ObjectAce ) { // // determine what should be the object/inherited object types on the merge split // GetObjectTypesForSplit( ace as ObjectAce, ms_AccessMask /* access mask for this split */, mergeResultFlags /* flags for this split */, out ms_ObjectAceFlags, out ms_ObjectAceType, out ms_InheritedObjectAceType ); } } } // // If this is no longer an evaluation, go ahead and make the changes // if ( !evaluationPass ) { QualifiedAce newAce; // // Modify the existing ACE in-place if it has any access // mask bits left, otherwise simply remove it // However, if for an object ace we are removing the object type // then we should really remove this ace and add a new one since // we would be changing the size of this ace // if ( ps_AccessMask != 0 ) { if (( ace is ObjectAce ) && (((( ObjectAce) ace ).ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent ) != 0 ) && (( ps_ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent ) == 0 )) { ObjectAce newObjectAce; _acl.RemoveAce(i); newObjectAce = new ObjectAce( ps_AceFlags, qualifier, ps_AccessMask, ace.SecurityIdentifier, ps_ObjectAceFlags, ps_ObjectAceType, ps_InheritedObjectAceType, false, null ); _acl.InsertAce( i, newObjectAce ); } else { ace.AceFlags = ps_AceFlags; ace.AccessMask = ps_AccessMask; if ( ace is ObjectAce ) { ObjectAce objectAce = ace as ObjectAce; objectAce.ObjectAceFlags = ps_ObjectAceFlags; objectAce.ObjectAceType = ps_ObjectAceType; objectAce.InheritedObjectAceType = ps_InheritedObjectAceType; } } } else { _acl.RemoveAce(i); i--; // keep the array index honest } // // On a SACL, the result of the auditing split must be recorded // if ( saclSemantics && (( as_AceFlags & AceFlags.AuditFlags ) != 0 )) { if ( ace is CommonAce ) { newAce = new CommonAce( as_AceFlags, qualifier, as_AccessMask, ace.SecurityIdentifier, false, null ); } else { // object ace newAce = new ObjectAce( as_AceFlags, qualifier, as_AccessMask, ace.SecurityIdentifier, as_ObjectAceFlags, as_ObjectAceType, as_InheritedObjectAceType, false, null ); } i++; // so it's not considered again _acl.InsertAce( i, newAce ); } // // If there are interesting bits left over from a remove, store them // as a separate ACE // if ( !mergeRemoveTotal ) { if ( ace is CommonAce ) { newAce = new CommonAce( mergeResultFlags, qualifier, ms_AccessMask, ace.SecurityIdentifier, false, null ); } else { // object ace newAce = new ObjectAce( mergeResultFlags, qualifier, ms_AccessMask, ace.SecurityIdentifier, ms_ObjectAceFlags, ms_ObjectAceType, ms_InheritedObjectAceType, false, null ); } i++; // so it's not considered again _acl.InsertAce( i, newAce ); } } } } catch( OverflowException ) { // // Oops, overflow means that the ACL became too big. // Inform the caller that the remove was not possible. // _acl.SetBinaryForm( recovery, 0 ); return false; } // // Finished evaluating the possibility of a remove. // If it looks like it's doable, go ahead and do it. // if ( evaluationPass && removePossible ) { evaluationPass = false; goto MakeAnotherPass; } OnAclModificationTried(); return removePossible; }
internal void AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, int accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { GenericAce ace; if (sid == null) { throw new ArgumentNullException("sid"); } this.ThrowIfNotCanonical(); bool flag = false; if ((qualifier == AceQualifier.SystemAudit) && (((byte) (flags & AceFlags.AuditFlags)) == 0)) { throw new ArgumentException(Environment.GetResourceString("Arg_EnumAtLeastOneFlag"), "flags"); } if (accessMask == 0) { throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "accessMask"); } if (!this.IsDS || (objectFlags == ObjectAceFlags.None)) { ace = new CommonAce(flags, qualifier, accessMask, sid, false, null); } else { ace = new ObjectAce(flags, qualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, false, null); } if (this.InspectAce(ref ace, this is DiscretionaryAcl)) { for (int i = 0; i < this.Count; i++) { QualifiedAce ace2 = this._acl[i] as QualifiedAce; if ((ace2 != null) && this.MergeAces(ref ace2, ace as QualifiedAce)) { flag = true; break; } } if (!flag) { this._acl.InsertAce(this._acl.Count, ace); this._isDirty = true; } this.OnAclModificationTried(); } }