internal QualifiedAce (InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AceQualifier aceQualifier, bool isCallback, byte [] opaque) : base (inheritanceFlags, propagationFlags) { ace_qualifier = aceQualifier; is_callback = isCallback; SetOpaque (opaque); }
internal QualifiedAce(InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AceQualifier aceQualifier, bool isCallback, byte [] opaque) : base(inheritanceFlags, propagationFlags) { ace_qualifier = aceQualifier; is_callback = isCallback; SetOpaque(opaque); }
private static AceType TypeFromQualifier(bool isCallback, AceQualifier qualifier) { switch (qualifier) { case AceQualifier.AccessAllowed: if (isCallback) { return(AceType.AccessAllowedCallbackObject); } return(AceType.AccessAllowedObject); case AceQualifier.AccessDenied: if (isCallback) { return(AceType.AccessDeniedCallbackObject); } return(AceType.AccessDeniedObject); case AceQualifier.SystemAudit: if (isCallback) { return(AceType.SystemAuditCallbackObject); } return(AceType.SystemAuditObject); case AceQualifier.SystemAlarm: if (isCallback) { return(AceType.SystemAlarmCallbackObject); } return(AceType.SystemAlarmObject); } throw new ArgumentOutOfRangeException("qualifier", Environment.GetResourceString("ArgumentOutOfRange_Enum")); }
// Constructor. public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(flags, (AceType)qualifier, accessMask, sid, opaque, qualifier, isCallback) { // Nothing to do here. }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) { }
private static AceType ConvertType(AceQualifier qualifier, bool isCallback) { switch(qualifier) { case AceQualifier.AccessAllowed: if (isCallback) return AceType.AccessAllowedCallbackObject; else return AceType.AccessAllowedObject; case AceQualifier.AccessDenied: if (isCallback) return AceType.AccessDeniedCallbackObject; else return AceType.AccessDeniedObject; case AceQualifier.SystemAlarm: if (isCallback) return AceType.SystemAlarmCallbackObject; else return AceType.SystemAlarmObject; case AceQualifier.SystemAudit: if (isCallback) return AceType.SystemAuditCallbackObject; else return AceType.SystemAuditObject; default: throw new ArgumentException("Unrecognized ACE qualifier: " + qualifier, "qualifier"); } }
/// <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; }
QualifiedAce AddAceGetQualifiedAce(AceQualifier aceQualifier, SecurityIdentifier sid, int accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { if (!IsDS) { throw new InvalidOperationException("For this overload, IsDS must be true."); } if (ObjectAceFlags.None == objectFlags) { return(AddAceGetQualifiedAce(aceQualifier, sid, accessMask, inheritanceFlags, propagationFlags, auditFlags)); } AceFlags flags = GetAceFlags(inheritanceFlags, propagationFlags, auditFlags); return(new ObjectAce(flags, aceQualifier, accessMask, sid, objectFlags, objectType, inheritedObjectType, false, null)); }
public CommonAce (AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base (InheritanceFlags.None, PropagationFlags.None, qualifier, isCallback, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(InheritanceFlags.None, PropagationFlags.None, qualifier, isCallback, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
/// <summary>Initiates a new instance of the <see cref="T:System.Security.AccessControl.ObjectAce" /> class.</summary> /// <param name="aceFlags">The inheritance, inheritance propagation, and auditing conditions for the new Access Control Entry (ACE).</param> /// <param name="qualifier">The use of the new ACE.</param> /// <param name="accessMask">The access mask for the ACE.</param> /// <param name="sid">The <see cref="T:System.Security.Principal.SecurityIdentifier" /> associated with the new ACE.</param> /// <param name="flags">Whether the <paramref name="type" /> and <paramref name="inheritedType" /> parameters contain valid object GUIDs.</param> /// <param name="type">A GUID that identifies the object type to which the new ACE applies.</param> /// <param name="inheritedType">A GUID that identifies the object type that can inherit the new ACE.</param> /// <param name="isCallback">true if the new ACE is a callback type ACE.</param> /// <param name="opaque">Opaque data associated with the new ACE. This is allowed only for callback ACE types. The length of this array must not be greater than the return value of the <see cref="M:System.Security.AccessControl.ObjectAceMaxOpaqueLength" /> method.</param> /// <exception cref="T:System.ArgumentOutOfRangeException">The qualifier parameter contains an invalid value or the length of the value of the opaque parameter is greater than the return value of the <see cref="M:System.Security.AccessControl.ObjectAceMaxOpaqueLength" /> method.</exception> public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base(InheritanceFlags.None, PropagationFlags.None, qualifier, isCallback, opaque) { base.AceFlags = aceFlags; base.SecurityIdentifier = sid; this.object_ace_flags = flags; this.object_ace_type = type; this.inherited_object_type = inheritedType; }
private static object[] CommonAce_CreateTestData(int intFlags, int intQualifier, int accessMask, string stringsid, bool isCallback, int opaqueLength, int offset) { AceFlags flags = (AceFlags)intFlags; AceQualifier qualifier = (AceQualifier)intQualifier; SecurityIdentifier sid = new SecurityIdentifier(stringsid); byte[] opaque = new byte[opaqueLength]; CommonAce ace = new CommonAce(flags, qualifier, accessMask, sid, isCallback, opaque); Assert.Equal(flags, ace.AceFlags); Assert.Equal(accessMask, ace.AccessMask); Assert.Equal(sid, ace.SecurityIdentifier); Assert.Equal(opaque, ace.GetOpaque()); Assert.Equal(qualifier, ace.AceQualifier); Assert.Equal(isCallback, ace.IsCallback); byte[] binaryForm = new byte[ace.BinaryLength + offset]; switch (qualifier) { case AceQualifier.AccessAllowed: binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessAllowedCallback : (byte)AceType.AccessAllowed; break; case AceQualifier.AccessDenied: binaryForm[offset + 0] = isCallback ? (byte)AceType.AccessDeniedCallback : (byte)AceType.AccessDenied; break; case AceQualifier.SystemAudit: binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAuditCallback : (byte)AceType.SystemAudit; break; case AceQualifier.SystemAlarm: binaryForm[offset + 0] = isCallback ? (byte)AceType.SystemAlarmCallback : (byte)AceType.SystemAlarm; break; default: return(null); } binaryForm[offset + 1] = (byte)flags; binaryForm[offset + 2] = (byte)(ace.BinaryLength >> 0); binaryForm[offset + 3] = (byte)(ace.BinaryLength >> 8); int baseOffset = offset + 4; int offsetLocal = 0; binaryForm[baseOffset + 0] = (byte)(accessMask >> 0); binaryForm[baseOffset + 1] = (byte)(accessMask >> 8); binaryForm[baseOffset + 2] = (byte)(accessMask >> 16); binaryForm[baseOffset + 3] = (byte)(accessMask >> 24); offsetLocal += 4; sid.GetBinaryForm(binaryForm, baseOffset + offsetLocal); offsetLocal += sid.BinaryLength; opaque.CopyTo(binaryForm, baseOffset + offsetLocal); return(new object[] { ace, binaryForm, offset }); }
// Constructor. internal QualifiedAce(AceFlags aceFlags, AceType aceType, int accessMask, SecurityIdentifier securityIdentifier, byte[] opaque, AceQualifier aceQualifier, bool isCallback) : base(aceFlags, aceType, accessMask, securityIdentifier) { this.opaque = opaque; this.aceQualifier = aceQualifier; this.isCallback = isCallback; }
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(ConvertType(qualifier, isCallback), flags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
QualifiedAce AddAceGetQualifiedAce(AceQualifier aceQualifier, SecurityIdentifier sid, int accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags) { AceFlags flags = GetAceFlags(inheritanceFlags, propagationFlags, auditFlags); return(new CommonAce(flags, aceQualifier, accessMask, sid, false, null)); }
public CommonAce (AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(ConvertType (qualifier, isCallback), flags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
// DiscretionaryAcl/SystemAcl shared implementation below... internal void AddAce(AceQualifier aceQualifier, SecurityIdentifier sid, int accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags) { QualifiedAce ace = AddAceGetQualifiedAce(aceQualifier, sid, accessMask, inheritanceFlags, propagationFlags, auditFlags); AddAce(ace); }
public static RawAcl CreateRawAclFromString(string rawAclString) { RawAcl rawAcl = null; byte revision = 0; int capacity = 1; CommonAce cAce = null; AceFlags aceFlags = AceFlags.None; AceQualifier aceQualifier = AceQualifier.AccessAllowed; int accessMask = 1; SecurityIdentifier sid = null; bool isCallback = false; int opaqueSize = 0; byte[] opaque = null; string[] parts = null; string[] subparts = null; char[] delimiter1 = new char[] { '#' }; char[] delimiter2 = new char[] { ':' }; if (rawAclString != null) { rawAcl = new RawAcl(revision, capacity); parts = rawAclString.Split(delimiter1); for (int i = 0; i < parts.Length; i++) { subparts = parts[i].Split(delimiter2); if (subparts.Length != 6) { return(null); } aceFlags = (AceFlags)byte.Parse(subparts[0]); aceQualifier = (AceQualifier)int.Parse(subparts[1]); accessMask = int.Parse(subparts[2]); sid = new SecurityIdentifier(TranslateStringConstFormatSidToStandardFormatSid(subparts[3])); isCallback = bool.Parse(subparts[4]); if (!isCallback) { opaque = null; } else { opaqueSize = int.Parse(subparts[5]); opaque = new byte[opaqueSize]; } cAce = new CommonAce(aceFlags, aceQualifier, accessMask, sid, isCallback, opaque); rawAcl.InsertAce(rawAcl.Count, cAce); } } return(rawAcl); }
protected static void VerifyObjectAce(ObjectAce ace, AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) { Assert.Equal(aceFlags, ace.AceFlags); Assert.Equal(accessMask, ace.AccessMask); Assert.Equal(sid, ace.SecurityIdentifier); Assert.Equal(opaque, ace.GetOpaque()); Assert.Equal(qualifier, ace.AceQualifier); Assert.Equal(isCallback, ace.IsCallback); Assert.Equal(flags, ace.ObjectAceFlags); Assert.Equal(type, ace.ObjectAceType); Assert.Equal(inheritedType, ace.InheritedObjectAceType); }
internal override int GetAceInsertPosition(AceQualifier aceQualifier) { // Canonical order for DACLs is explicit deny, explicit allow, inherited. if (AceQualifier.AccessAllowed == aceQualifier) { return(GetCanonicalExplicitDenyAceCount()); } else { return(0); } }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base(ConvertType(qualifier, isCallback), aceFlags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; ObjectAceFlags = flags; ObjectAceType = type; InheritedObjectAceType = inheritedType; }
public ObjectAce (AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base (ConvertType(qualifier, isCallback), aceFlags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; ObjectAceFlags = flags; ObjectAceType = type; InheritedObjectAceType = inheritedType; }
public ObjectAce (AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base (InheritanceFlags.None, PropagationFlags.None, qualifier, isCallback, opaque) { AceFlags = aceFlags; SecurityIdentifier = sid; object_ace_flags = flags; object_ace_type = type; inherited_object_type = inheritedType; }
internal void AddAce(AceQualifier aceQualifier, SecurityIdentifier sid, int accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType) { QualifiedAce ace = AddAceGetQualifiedAce(aceQualifier, sid, accessMask, inheritanceFlags, propagationFlags, auditFlags, objectFlags, objectType, inheritedObjectType); AddAce(ace); }
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 static AceType TypeFromQualifier(bool isCallback, AceQualifier qualifier) { switch (qualifier) { case AceQualifier.AccessAllowed: return(!isCallback ? AceType.AccessAllowed : AceType.AccessAllowedCallback); case AceQualifier.AccessDenied: return(!isCallback ? AceType.AccessDenied : AceType.AccessDeniedCallback); case AceQualifier.SystemAudit: return(!isCallback ? AceType.SystemAudit : AceType.SystemAuditCallback); case AceQualifier.SystemAlarm: return(!isCallback ? AceType.SystemAlarm : AceType.SystemAlarmCallback); default: throw new ArgumentOutOfRangeException("qualifier", Environment.GetResourceString("ArgumentOutOfRange_Enum")); } }
internal void RemoveAceSpecific(AceQualifier aceQualifier, SecurityIdentifier sid, int accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags auditFlags) { RequireCanonicity(); RemoveAces <CommonAce> (ace => { if (ace.AccessMask != accessMask) { return(false); } if (ace.AceQualifier != aceQualifier) { return(false); } if (ace.SecurityIdentifier != sid) { return(false); } if (ace.InheritanceFlags != inheritanceFlags) { return(false); } if (InheritanceFlags.None != inheritanceFlags) { if (ace.PropagationFlags != propagationFlags) { return(false); } } if (ace.AuditFlags != auditFlags) { return(false); } return(true); }); CleanAndRetestCanonicity(); }
// // Based on the is-callback and qualifier information, // computes the numerical type of the ACE // private static AceType TypeFromQualifier(bool isCallback, AceQualifier qualifier) { // // Might benefit from replacing this with a static hard-coded table // switch (qualifier) { case AceQualifier.AccessAllowed: return isCallback ? AceType.AccessAllowedCallback : AceType.AccessAllowed; case AceQualifier.AccessDenied: return isCallback ? AceType.AccessDeniedCallback : AceType.AccessDenied; case AceQualifier.SystemAudit: return isCallback ? AceType.SystemAuditCallback : AceType.SystemAudit; case AceQualifier.SystemAlarm: return isCallback ? AceType.SystemAlarmCallback : AceType.SystemAlarm; default: throw new ArgumentOutOfRangeException( nameof(qualifier), SR.ArgumentOutOfRange_Enum); } }
// // The constructor computes the type of this ACE and passes the rest // to the base class constructor // public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(TypeFromQualifier(isCallback, qualifier), flags, accessMask, sid, opaque) { }
internal QualifiedAce(AceType type, AceFlags flags, int accessMask, SecurityIdentifier sid, byte[] opaque) : base(type, flags, accessMask, sid) { _qualifier = QualifierFromType(type, out _isCallback); SetOpaque(opaque); }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, System.Security.Principal.SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base (default(AceType), default(AceFlags), default(int), default(System.Security.Principal.SecurityIdentifier), default(byte[])) { }
private static AceType TypeFromQualifier(bool isCallback, AceQualifier qualifier) { switch (qualifier) { case AceQualifier.AccessAllowed: if (isCallback) { return AceType.AccessAllowedCallback; } return AceType.AccessAllowed; case AceQualifier.AccessDenied: if (isCallback) { return AceType.AccessDeniedCallback; } return AceType.AccessDenied; case AceQualifier.SystemAudit: if (isCallback) { return AceType.SystemAuditCallback; } return AceType.SystemAudit; case AceQualifier.SystemAlarm: if (isCallback) { return AceType.SystemAlarmCallback; } return AceType.SystemAlarm; } throw new ArgumentOutOfRangeException("qualifier", Environment.GetResourceString("ArgumentOutOfRange_Enum")); }
private static AceType TypeFromQualifier(bool isCallback, AceQualifier qualifier) { switch (qualifier) { case AceQualifier.AccessAllowed: return isCallback ? AceType.AccessAllowedCallbackObject : AceType.AccessAllowedObject; case AceQualifier.AccessDenied: return isCallback ? AceType.AccessDeniedCallbackObject : AceType.AccessDeniedObject; case AceQualifier.SystemAudit: return isCallback ? AceType.SystemAuditCallbackObject : AceType.SystemAuditObject; case AceQualifier.SystemAlarm: return isCallback ? AceType.SystemAlarmCallbackObject : AceType.SystemAlarmObject; default: throw new ArgumentOutOfRangeException( nameof(qualifier), SR.ArgumentOutOfRange_Enum); } }
public static void RemoveInheritedAces_BasicValidationTestCases() { bool isContainer = false; bool isDS = false; RawAcl rawAcl = null; DiscretionaryAcl discretionaryAcl = null; GenericAce gAce = null; byte revision = 0; int capacity = 0; //CustomAce constructor parameters AceType aceType = AceType.AccessAllowed; AceFlags aceFlag = AceFlags.None; byte[] opaque = null; //CompoundAce constructor additional parameters int accessMask = 0; CompoundAceType compoundAceType = CompoundAceType.Impersonation; string sid = "BG"; //CommonAce constructor additional parameters AceQualifier aceQualifier = 0; //ObjectAce constructor additional parameters ObjectAceFlags objectAceFlag = 0; Guid objectAceType; Guid inheritedObjectAceType; //case 1, no Ace revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 2, only have explicit Ace revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //199 has all AceFlags except InheritOnly and Inherited gAce = new CommonAce((AceFlags)199, AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 3, non-inherited CommonAce, ObjectAce, CompoundAce, CustomAce revision = 127; capacity = 5; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")).ToString(); rawAcl = new RawAcl(revision, capacity); aceFlag = AceFlags.InheritanceFlags; accessMask = 1; //Access Allowed CommonAce gAce = new CommonAce(aceFlag, AceQualifier.AccessAllowed, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 1.ToString())), false, null); rawAcl.InsertAce(0, gAce); //Access Dennied CommonAce gAce = new CommonAce(aceFlag, AceQualifier.AccessDenied, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 2.ToString())), false, null); rawAcl.InsertAce(0, gAce); //CustomAce aceType = AceType.MaxDefinedAceType + 1; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(2, gAce); //CompoundAce compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 3.ToString()))); rawAcl.InsertAce(3, gAce); //ObjectAce aceQualifier = AceQualifier.AccessAllowed; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 4.ToString())), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(2, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException Assert.Throws <InvalidOperationException>(() => { TestRemoveInheritedAces(discretionaryAcl); }); //case 4, all inherited CommonAce, ObjectAce, CompoundAce, CustomAce revision = 127; capacity = 5; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")).ToString(); rawAcl = new RawAcl(revision, capacity); aceFlag = AceFlags.InheritanceFlags | AceFlags.Inherited; accessMask = 1; //Access Allowed CommonAce gAce = new CommonAce(aceFlag, AceQualifier.AccessAllowed, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 1.ToString())), false, null); rawAcl.InsertAce(0, gAce); //Access Dennied CommonAce gAce = new CommonAce(aceFlag, AceQualifier.AccessDenied, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 2.ToString())), false, null); rawAcl.InsertAce(0, gAce); //CustomAce aceType = AceType.MaxDefinedAceType + 1; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); //CompoundAce compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 3.ToString()))); rawAcl.InsertAce(0, gAce); //ObjectAce aceQualifier = AceQualifier.AccessAllowed; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 4.ToString())), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 5, only have one inherit Ace revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //215 has all AceFlags except InheritOnly gAce = new CommonAce((AceFlags)215, AceQualifier.AccessDenied, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 6, have one explicit Ace and one inherited Ace revision = 255; capacity = 1; rawAcl = new RawAcl(revision, capacity); //199 has all AceFlags except InheritOnly and Inherited gAce = new CommonAce((AceFlags)(FlagsForAce.AuditFlags | FlagsForAce.OI | FlagsForAce.CI | FlagsForAce.NP), AceQualifier.AccessDenied, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")), false, null); rawAcl.InsertAce(0, gAce); //215 has all AceFlags except InheritOnly gAce = new CommonAce((AceFlags)(FlagsForAce.AuditFlags | FlagsForAce.OI | FlagsForAce.CI | FlagsForAce.NP | FlagsForAce.IH), AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null); rawAcl.InsertAce(1, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 7, have two inherited Aces revision = 255; capacity = 1; rawAcl = new RawAcl(revision, capacity); //215 has all AceFlags except InheritOnly gAce = new CommonAce((AceFlags)215, AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")), false, null); rawAcl.InsertAce(0, gAce); sid = "BA"; //16 has Inherited gAce = new CommonAce((AceFlags)16, AceQualifier.AccessDenied, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BA")), false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 8, 1 inherited CustomAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceType = AceType.MaxDefinedAceType + 1; //215 has all AceFlags except InheritOnly aceFlag = (AceFlags)215; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 9, 1 inherited CompoundAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceFlag = (AceFlags)223; //all flags ored together accessMask = 1; compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid))); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); //case 10, 1 inherited ObjectAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceFlag = (AceFlags)223; //all flags ored together aceQualifier = AceQualifier.AccessAllowed; accessMask = 1; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = true; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(TestRemoveInheritedAces(discretionaryAcl)); }
internal override int GetAceInsertPosition (AceQualifier aceQualifier) { return 0; }
// // 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(); }
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, System.Security.Principal.SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(default(AceType), default(AceFlags), default(int), default(System.Security.Principal.SecurityIdentifier), default(byte[])) { }
internal static bool ParseBinaryForm(byte[] binaryForm, int offset, out AceQualifier qualifier, out int accessMask, out SecurityIdentifier sid, out bool isCallback, out byte[] opaque) { int num; GenericAce.VerifyHeader(binaryForm, offset); if ((binaryForm.Length - offset) < (8 + SecurityIdentifier.MinBinaryLength)) { goto Label_0114; } AceType type = (AceType) binaryForm[offset]; switch (type) { case AceType.AccessAllowed: case AceType.AccessDenied: case AceType.SystemAudit: case AceType.SystemAlarm: isCallback = false; break; default: if (((type != AceType.AccessAllowedCallback) && (type != AceType.AccessDeniedCallback)) && ((type != AceType.SystemAuditCallback) && (type != AceType.SystemAlarmCallback))) { goto Label_0114; } isCallback = true; break; } switch (type) { case AceType.AccessAllowed: case AceType.AccessAllowedCallback: qualifier = AceQualifier.AccessAllowed; break; default: switch (type) { case AceType.AccessDenied: case AceType.AccessDeniedCallback: qualifier = AceQualifier.AccessDenied; goto Label_0084; case AceType.SystemAudit: case AceType.SystemAuditCallback: qualifier = AceQualifier.SystemAudit; goto Label_0084; } if ((type != AceType.SystemAlarm) && (type != AceType.SystemAlarmCallback)) { goto Label_0114; } qualifier = AceQualifier.SystemAlarm; break; } Label_0084: num = offset + 4; int num2 = 0; accessMask = ((binaryForm[num] + (binaryForm[num + 1] << 8)) + (binaryForm[num + 2] << 0x10)) + (binaryForm[num + 3] << 0x18); num2 += 4; sid = new SecurityIdentifier(binaryForm, num + num2); opaque = null; int num3 = (binaryForm[offset + 3] << 8) + binaryForm[offset + 2]; if ((num3 % 4) == 0) { int num4 = ((num3 - 4) - 4) - ((byte) sid.BinaryLength); if (num4 > 0) { opaque = new byte[num4]; for (int i = 0; i < num4; i++) { opaque[i] = binaryForm[((offset + num3) - num4) + i]; } } return true; } Label_0114: qualifier = AceQualifier.AccessAllowed; accessMask = 0; sid = null; isCallback = false; opaque = null; return false; }
private static AceType TypeFromQualifier( bool isCallback, AceQualifier qualifier ) { switch ( qualifier ) { case AceQualifier.AccessAllowed: return isCallback ? AceType.AccessAllowedCallbackObject : AceType.AccessAllowedObject; case AceQualifier.AccessDenied: return isCallback ? AceType.AccessDeniedCallbackObject : AceType.AccessDeniedObject; case AceQualifier.SystemAudit: return isCallback ? AceType.SystemAuditCallbackObject : AceType.SystemAuditObject; case AceQualifier.SystemAlarm: return isCallback ? AceType.SystemAlarmCallbackObject : AceType.SystemAlarmObject; default: throw new ArgumentOutOfRangeException( "qualifier", Environment.GetResourceString( "ArgumentOutOfRange_Enum" )); } }
// // Called by GenericAce.CreateFromBinaryForm to parse the binary // form of the common ACE and extract the useful pieces. // internal static bool ParseBinaryForm( byte[] binaryForm, int offset, out AceQualifier qualifier, out int accessMask, out SecurityIdentifier sid, out bool isCallback, out byte[] opaque) { // // Verify the ACE header // VerifyHeader(binaryForm, offset); // // Verify the length field // if (binaryForm.Length - offset < HeaderLength + AccessMaskLength + SecurityIdentifier.MinBinaryLength) { goto InvalidParameter; } // // Identify callback ACE types // AceType type = (AceType)binaryForm[offset]; if (type == AceType.AccessAllowed || type == AceType.AccessDenied || type == AceType.SystemAudit || type == AceType.SystemAlarm) { isCallback = false; } else if (type == AceType.AccessAllowedCallback || type == AceType.AccessDeniedCallback || type == AceType.SystemAuditCallback || type == AceType.SystemAlarmCallback) { isCallback = true; } else { goto InvalidParameter; } // // Compute the qualifier from the ACE type // if (type == AceType.AccessAllowed || type == AceType.AccessAllowedCallback) { qualifier = AceQualifier.AccessAllowed; } else if (type == AceType.AccessDenied || type == AceType.AccessDeniedCallback) { qualifier = AceQualifier.AccessDenied; } else if (type == AceType.SystemAudit || type == AceType.SystemAuditCallback) { qualifier = AceQualifier.SystemAudit; } else if (type == AceType.SystemAlarm || type == AceType.SystemAlarmCallback) { qualifier = AceQualifier.SystemAlarm; } else { goto InvalidParameter; } int baseOffset = offset + HeaderLength; int offsetLocal = 0; // // The access mask is stored in big-endian format // accessMask = (int)( (((uint)binaryForm[baseOffset + 0]) << 0) + (((uint)binaryForm[baseOffset + 1]) << 8) + (((uint)binaryForm[baseOffset + 2]) << 16) + (((uint)binaryForm[baseOffset + 3]) << 24)); offsetLocal += AccessMaskLength; // // The access mask is followed by the SID // sid = new SecurityIdentifier(binaryForm, baseOffset + offsetLocal); // // The rest of the blob is occupied by opaque callback data, if such is supported // opaque = null; int aceLength = (binaryForm[offset + 3] << 8) + (binaryForm[offset + 2] << 0); if (aceLength % 4 != 0) { goto InvalidParameter; } int opaqueLength = aceLength - HeaderLength - AccessMaskLength - (byte)sid.BinaryLength; if (opaqueLength > 0) { opaque = new byte[opaqueLength]; for (int i = 0; i < opaqueLength; i++) { opaque[i] = binaryForm[offset + aceLength - opaqueLength + i]; } } return true; InvalidParameter: qualifier = 0; accessMask = 0; sid = null; isCallback = false; opaque = null; return false; }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque) : base(TypeFromQualifier(isCallback, qualifier), aceFlags, accessMask, sid, opaque) { _objectFlags = flags; _objectAceType = type; _inheritedObjectAceType = inheritedType; }
private static AceType ConvertType (AceQualifier qualifier, bool isCallback) { switch (qualifier) { case AceQualifier.AccessAllowed: if (isCallback) return AceType.AccessAllowedCallback; else return AceType.AccessAllowed; case AceQualifier.AccessDenied: if (isCallback) return AceType.AccessDeniedCallback; else return AceType.AccessDenied; case AceQualifier.SystemAlarm: if (isCallback) return AceType.SystemAlarmCallback; else return AceType.SystemAlarm; case AceQualifier.SystemAudit: if (isCallback) return AceType.SystemAuditCallback; else return AceType.SystemAudit; default: throw new ArgumentException ("Unrecognized ACE qualifier: " + qualifier, "qualifier"); } }
// // Called by GenericAce.CreateFromBinaryForm to parse the binary form // of the object ACE and extract the useful pieces // internal static bool ParseBinaryForm( byte[] binaryForm, int offset, out AceQualifier qualifier, out int accessMask, out SecurityIdentifier sid, out ObjectAceFlags objectFlags, out Guid objectAceType, out Guid inheritedObjectAceType, out bool isCallback, out byte[] opaque) { byte[] guidArray = new byte[GuidLength]; // // Verify the ACE header // VerifyHeader(binaryForm, offset); // // Verify the length field // if (binaryForm.Length - offset < HeaderLength + AccessMaskLength + ObjectFlagsLength + SecurityIdentifier.MinBinaryLength) { goto InvalidParameter; } // // Identify callback ACE types // AceType type = (AceType)binaryForm[offset]; if (type == AceType.AccessAllowedObject || type == AceType.AccessDeniedObject || type == AceType.SystemAuditObject || type == AceType.SystemAlarmObject) { isCallback = false; } else if (type == AceType.AccessAllowedCallbackObject || type == AceType.AccessDeniedCallbackObject || type == AceType.SystemAuditCallbackObject || type == AceType.SystemAlarmCallbackObject) { isCallback = true; } else { goto InvalidParameter; } // // Compute the qualifier from the ACE type // if (type == AceType.AccessAllowedObject || type == AceType.AccessAllowedCallbackObject) { qualifier = AceQualifier.AccessAllowed; } else if (type == AceType.AccessDeniedObject || type == AceType.AccessDeniedCallbackObject) { qualifier = AceQualifier.AccessDenied; } else if (type == AceType.SystemAuditObject || type == AceType.SystemAuditCallbackObject) { qualifier = AceQualifier.SystemAudit; } else if (type == AceType.SystemAlarmObject || type == AceType.SystemAlarmCallbackObject) { qualifier = AceQualifier.SystemAlarm; } else { goto InvalidParameter; } int baseOffset = offset + HeaderLength; int offsetLocal = 0; accessMask = (int)( (((uint)binaryForm[baseOffset + 0]) << 0) + (((uint)binaryForm[baseOffset + 1]) << 8) + (((uint)binaryForm[baseOffset + 2]) << 16) + (((uint)binaryForm[baseOffset + 3]) << 24)); offsetLocal += AccessMaskLength; objectFlags = (ObjectAceFlags)( (((uint)binaryForm[baseOffset + offsetLocal + 0]) << 0) + (((uint)binaryForm[baseOffset + offsetLocal + 1]) << 8) + (((uint)binaryForm[baseOffset + offsetLocal + 2]) << 16) + (((uint)binaryForm[baseOffset + offsetLocal + 3]) << 24)); offsetLocal += ObjectFlagsLength; if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != 0) { for (int i = 0; i < GuidLength; i++) { guidArray[i] = binaryForm[baseOffset + offsetLocal + i]; } offsetLocal += GuidLength; } else { for (int i = 0; i < GuidLength; i++) { guidArray[i] = 0; } } objectAceType = new Guid(guidArray); if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0) { for (int i = 0; i < GuidLength; i++) { guidArray[i] = binaryForm[baseOffset + offsetLocal + i]; } offsetLocal += GuidLength; } else { for (int i = 0; i < GuidLength; i++) { guidArray[i] = 0; } } inheritedObjectAceType = new Guid(guidArray); sid = new SecurityIdentifier(binaryForm, baseOffset + offsetLocal); opaque = null; int aceLength = (binaryForm[offset + 3] << 8) + (binaryForm[offset + 2] << 0); if (aceLength % 4 != 0) { goto InvalidParameter; } int opaqueLength = (aceLength - HeaderLength - AccessMaskLength - ObjectFlagsLength - (byte)sid.BinaryLength); if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != 0) { opaqueLength -= GuidLength; } if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0) { opaqueLength -= GuidLength; } if (opaqueLength > 0) { opaque = new byte[opaqueLength]; for (int i = 0; i < opaqueLength; i++) { opaque[i] = binaryForm[offset + aceLength - opaqueLength + i]; } } return true; InvalidParameter: qualifier = 0; accessMask = 0; sid = null; objectFlags = 0; objectAceType = Guid.NewGuid(); inheritedObjectAceType = Guid.NewGuid(); isCallback = false; opaque = null; return false; }
public static void Purge_BasicValidationTestCases() { bool isContainer = false; bool isDS = false; RawAcl rawAcl = null; DiscretionaryAcl discretionaryAcl = null; int aceCount = 0; SecurityIdentifier sid = null; GenericAce gAce = null; byte revision = 0; int capacity = 0; //CustomAce constructor parameters AceType aceType = AceType.AccessAllowed; AceFlags aceFlag = AceFlags.None; byte[] opaque = null; //CompoundAce constructor additional parameters int accessMask = 0; CompoundAceType compoundAceType = CompoundAceType.Impersonation; string sidStr = "LA"; //CommonAce constructor additional parameters AceQualifier aceQualifier = 0; //ObjectAce constructor additional parameters ObjectAceFlags objectAceFlag = 0; Guid objectAceType; Guid inheritedObjectAceType; //case 1, no Ace revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 0; sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); //case 2, only have 1 explicit Ace of the sid revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); //199 has all aceflags but inheritonly and inherited gAce = new CommonAce((AceFlags)199, AceQualifier.AccessAllowed, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); //case 3, only have 1 explicit Ace of different sid revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //199 has all aceflags but inheritedonly and inherited sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); gAce = new CommonAce((AceFlags)199, AceQualifier.AccessDenied, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 1; sidStr = "BA"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); //case 4, only have 1 inherited Ace of the sid revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); //215 has all aceflags but inheritedonly gAce = new CommonAce((AceFlags)215, AceQualifier.AccessAllowed, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 1; Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); //case 5, have one explicit Ace and one inherited Ace of the sid revision = 255; capacity = 1; rawAcl = new RawAcl(revision, capacity); sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); //199 has all aceflags but inheritedonly and inherited gAce = new CommonAce((AceFlags)(FlagsForAce.AuditFlags | FlagsForAce.OI | FlagsForAce.CI | FlagsForAce.NP), AceQualifier.AccessDenied, 1, sid, false, null); rawAcl.InsertAce(0, gAce); //215 has all aceflags but inheritedonly gAce = new CommonAce((AceFlags)(FlagsForAce.AuditFlags | FlagsForAce.OI | FlagsForAce.CI | FlagsForAce.NP | FlagsForAce.IH), AceQualifier.AccessAllowed, 2, sid, false, null); rawAcl.InsertAce(1, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 1; Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); //case 6, have two explicit Aces of the sid revision = 255; capacity = 1; rawAcl = new RawAcl(revision, capacity); sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); //207 has all AceFlags but inherited gAce = new CommonAce((AceFlags)207, AceQualifier.AccessAllowed, 1, sid, false, null); rawAcl.InsertAce(0, gAce); gAce = new CommonAce(AceFlags.None, AceQualifier.AccessDenied, 2, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(discretionaryAcl, sid, 0)); //case 7, 1 explicit CustomAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceType = AceType.MaxDefinedAceType + 1; //199 has all AceFlags except InheritOnly and Inherited aceFlag = (AceFlags)199; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")); aceCount = 1; //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException Assert.Throws <InvalidOperationException>(() => { TestPurge(discretionaryAcl, sid, aceCount); }); //case 8, 1 explicit CompoundAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); //207 has all AceFlags but inherited aceFlag = (AceFlags)207; accessMask = 1; compoundAceType = CompoundAceType.Impersonation; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")); gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, sid); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 0; //After Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical and //forbid the modification on uncanonical ACL, this case will throw InvalidOperationException Assert.Throws <InvalidOperationException>(() => { TestPurge(discretionaryAcl, sid, aceCount); }); //case 9, 1 explicit ObjectAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")); //207 has all AceFlags but inherited aceFlag = (AceFlags)207; aceQualifier = AceQualifier.AccessAllowed; accessMask = 1; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, sid, objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = true; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(discretionaryAcl, sid, aceCount)); }
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 && (( flags & AceFlags.AuditFlags ) == 0 )) { throw new ArgumentException( Environment.GetResourceString( "Arg_EnumAtLeastOneFlag" ), "flags" ); } if ( sid == null ) { throw new ArgumentNullException( "sid" ); } Contract.EndContractBlock(); ThrowIfNotCanonical(); 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; } // // Only interested in exact ACE flag matches // if ( ace.AceFlags != flags ) { continue; } // // Only interested in exact access mask matches // if ( ace.AccessMask != accessMask ) { continue; } if ( IsDS ) { // // Incase of object aces, only interested in ACEs which match in their // objectType and inheritedObjectType // if (( ace is ObjectAce ) && ( objectFlags != ObjectAceFlags.None )) { // // both are object aces, so must match in object type and inherited object type // ObjectAce objectAce = ace as ObjectAce; if (( !objectAce.ObjectTypesMatch( objectFlags, objectType )) || ( !objectAce.InheritedObjectTypesMatch( objectFlags, inheritedObjectType ))) { continue; } } else if (( ace is ObjectAce ) || ( objectFlags != ObjectAceFlags.None )) { // one is object ace and the other is not, so no match continue; } } // // Got our exact match; now remove it // _acl.RemoveAce(i); i--; // keep the array index honest } OnAclModificationTried(); }
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque);
public static void Constructor3_AdditionalTestCases() { bool isContainer = false; bool isDS = false; RawAcl rawAcl = null; DiscretionaryAcl discretionaryAcl = null; GenericAce gAce = null; byte revision = 0; int capacity = 0; //CustomAce constructor parameters AceType aceType = AceType.AccessAllowed; AceFlags aceFlag = AceFlags.None; byte[] opaque = null; //CompoundAce constructor additional parameters int accessMask = 0; CompoundAceType compoundAceType = CompoundAceType.Impersonation; string sid = "BG"; //CommonAce constructor additional parameters AceQualifier aceQualifier = 0; //ObjectAce constructor additional parameters ObjectAceFlags objectAceFlag = 0; Guid objectAceType; Guid inheritedObjectAceType; //case 1, an AccessAllowed ACE with a zero access mask is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); //drop the Ace from rawAcl rawAcl.RemoveAce(0); //the only ACE is a meaningless ACE, will be removed Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); //case 2, an inherit-only AccessDenied ACE on an object ACL is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //15 has all inheritance AceFlags but Inherited gAce = new CommonAce((AceFlags)15, AceQualifier.AccessDenied, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); rawAcl.RemoveAce(0); //the only ACE is a meaningless ACE, will be removed Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); //case 3, an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //8 has inheritOnly gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); rawAcl.RemoveAce(0); //the only ACE is a meaningless ACE, will be removed Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); //case 4, 1 CustomAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceType = AceType.MaxDefinedAceType + 1; aceFlag = AceFlags.None; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl)); //case 5, 1 CompoundAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); // 2 has ContainerInherit aceFlag = (AceFlags)2; accessMask = 1; compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid))); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl)); //case 6, 1 ObjectAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceFlag = (AceFlags)15; //all inheritance flags ored together but Inherited aceQualifier = AceQualifier.AccessAllowed; accessMask = 1; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = true; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); //case 7, no Ace revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); //case 8, all Aces from case 1, and 3 to 6 revision = 127; capacity = 5; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid("BG")).ToString(); rawAcl = new RawAcl(revision, capacity); //0 access Mask gAce = new CommonAce(AceFlags.None, AceQualifier.AccessAllowed, 0, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 1.ToString())), false, null); rawAcl.InsertAce(rawAcl.Count, gAce); //an inherit-only AccessAllowed ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed gAce = new CommonAce((AceFlags)8, AceQualifier.AccessAllowed, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 2.ToString())), false, null); rawAcl.InsertAce(rawAcl.Count, gAce); // ObjectAce aceFlag = (AceFlags)15; //all inheritance flags ored together but Inherited aceQualifier = AceQualifier.AccessAllowed; accessMask = 1; objectAceFlag = ObjectAceFlags.ObjectAceTypePresent | ObjectAceFlags.InheritedObjectAceTypePresent; objectAceType = new Guid("11111111-1111-1111-1111-111111111111"); inheritedObjectAceType = new Guid("22222222-2222-2222-2222-222222222222"); gAce = new ObjectAce(aceFlag, aceQualifier, accessMask, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 3.ToString())), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(rawAcl.Count, gAce); // CustomAce aceType = AceType.MaxDefinedAceType + 1; aceFlag = AceFlags.None; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(rawAcl.Count, gAce); // CompoundAce aceFlag = (AceFlags)2; accessMask = 1; compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid + 4.ToString()))); rawAcl.InsertAce(rawAcl.Count, gAce); isContainer = true; isDS = false; discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); rawAcl.RemoveAce(0); rawAcl.RemoveAce(0); //Mark changes design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, false, rawAcl)); discretionaryAcl = null; isContainer = false; isDS = false; rawAcl = null; //case 1, rawAcl = null discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); rawAcl = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1); Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); discretionaryAcl = new DiscretionaryAcl(isContainer, isDS, rawAcl); rawAcl = new RawAcl(isDS ? GenericAcl.AclRevisionDS : GenericAcl.AclRevision, 1); Assert.True(VerifyACL(discretionaryAcl, isContainer, isDS, true, rawAcl)); }
// Token: 0x06001E7A RID: 7802 RVA: 0x0006A800 File Offset: 0x00068A00 internal static bool ParseBinaryForm(byte[] binaryForm, int offset, out AceQualifier qualifier, out int accessMask, out SecurityIdentifier sid, out ObjectAceFlags objectFlags, out Guid objectAceType, out Guid inheritedObjectAceType, out bool isCallback, out byte[] opaque) { byte[] array = new byte[16]; GenericAce.VerifyHeader(binaryForm, offset); if (binaryForm.Length - offset >= 12 + SecurityIdentifier.MinBinaryLength) { AceType aceType = (AceType)binaryForm[offset]; if (aceType == AceType.AccessAllowedObject || aceType == AceType.AccessDeniedObject || aceType == AceType.SystemAuditObject || aceType == AceType.SystemAlarmObject) { isCallback = false; } else { if (aceType != AceType.AccessAllowedCallbackObject && aceType != AceType.AccessDeniedCallbackObject && aceType != AceType.SystemAuditCallbackObject && aceType != AceType.SystemAlarmCallbackObject) { goto IL_209; } isCallback = true; } if (aceType == AceType.AccessAllowedObject || aceType == AceType.AccessAllowedCallbackObject) { qualifier = AceQualifier.AccessAllowed; } else if (aceType == AceType.AccessDeniedObject || aceType == AceType.AccessDeniedCallbackObject) { qualifier = AceQualifier.AccessDenied; } else if (aceType == AceType.SystemAuditObject || aceType == AceType.SystemAuditCallbackObject) { qualifier = AceQualifier.SystemAudit; } else { if (aceType != AceType.SystemAlarmObject && aceType != AceType.SystemAlarmCallbackObject) { goto IL_209; } qualifier = AceQualifier.SystemAlarm; } int num = offset + 4; int num2 = 0; accessMask = (int)binaryForm[num] + ((int)binaryForm[num + 1] << 8) + ((int)binaryForm[num + 2] << 16) + ((int)binaryForm[num + 3] << 24); num2 += 4; objectFlags = (ObjectAceFlags)((int)binaryForm[num + num2] + ((int)binaryForm[num + num2 + 1] << 8) + ((int)binaryForm[num + num2 + 2] << 16) + ((int)binaryForm[num + num2 + 3] << 24)); num2 += 4; if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None) { for (int i = 0; i < 16; i++) { array[i] = binaryForm[num + num2 + i]; } num2 += 16; } else { for (int j = 0; j < 16; j++) { array[j] = 0; } } objectAceType = new Guid(array); if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != ObjectAceFlags.None) { for (int k = 0; k < 16; k++) { array[k] = binaryForm[num + num2 + k]; } num2 += 16; } else { for (int l = 0; l < 16; l++) { array[l] = 0; } } inheritedObjectAceType = new Guid(array); sid = new SecurityIdentifier(binaryForm, num + num2); opaque = null; int num3 = ((int)binaryForm[offset + 3] << 8) + (int)binaryForm[offset + 2]; if (num3 % 4 == 0) { int num4 = num3 - 4 - 4 - 4 - (int)((byte)sid.BinaryLength); if ((objectFlags & ObjectAceFlags.ObjectAceTypePresent) != ObjectAceFlags.None) { num4 -= 16; } if ((objectFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != ObjectAceFlags.None) { num4 -= 16; } if (num4 > 0) { opaque = new byte[num4]; for (int m = 0; m < num4; m++) { opaque[m] = binaryForm[offset + num3 - num4 + m]; } } return(true); } } IL_209: qualifier = AceQualifier.AccessAllowed; accessMask = 0; sid = null; objectFlags = ObjectAceFlags.None; objectAceType = Guid.NewGuid(); inheritedObjectAceType = Guid.NewGuid(); isCallback = false; opaque = null; return(false); }
// // 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(); }
internal static bool ParseBinaryForm(byte[] binaryForm, int offset, out AceQualifier qualifier, out int accessMask, out SecurityIdentifier sid, out System.Security.AccessControl.ObjectAceFlags objectFlags, out Guid objectAceType, out Guid inheritedObjectAceType, out bool isCallback, out byte[] opaque) { int num; byte[] b = new byte[0x10]; GenericAce.VerifyHeader(binaryForm, offset); if ((binaryForm.Length - offset) < (12 + SecurityIdentifier.MinBinaryLength)) { goto Label_0209; } AceType type = (AceType) binaryForm[offset]; switch (type) { case AceType.AccessAllowedObject: case AceType.AccessDeniedObject: case AceType.SystemAuditObject: case AceType.SystemAlarmObject: isCallback = false; break; default: if (((type != AceType.AccessAllowedCallbackObject) && (type != AceType.AccessDeniedCallbackObject)) && ((type != AceType.SystemAuditCallbackObject) && (type != AceType.SystemAlarmCallbackObject))) { goto Label_0209; } isCallback = true; break; } switch (type) { case AceType.AccessAllowedObject: case AceType.AccessAllowedCallbackObject: qualifier = AceQualifier.AccessAllowed; break; default: switch (type) { case AceType.AccessDeniedObject: case AceType.AccessDeniedCallbackObject: qualifier = AceQualifier.AccessDenied; goto Label_008F; case AceType.SystemAuditObject: case AceType.SystemAuditCallbackObject: qualifier = AceQualifier.SystemAudit; goto Label_008F; } if ((type != AceType.SystemAlarmObject) && (type != AceType.SystemAlarmCallbackObject)) { goto Label_0209; } qualifier = AceQualifier.SystemAlarm; break; } Label_008F: num = offset + 4; int num2 = 0; accessMask = ((binaryForm[num] + (binaryForm[num + 1] << 8)) + (binaryForm[num + 2] << 0x10)) + (binaryForm[num + 3] << 0x18); num2 += 4; objectFlags = (System.Security.AccessControl.ObjectAceFlags) (((binaryForm[num + num2] + (binaryForm[(num + num2) + 1] << 8)) + (binaryForm[(num + num2) + 2] << 0x10)) + (binaryForm[(num + num2) + 3] << 0x18)); num2 += 4; if ((objectFlags & System.Security.AccessControl.ObjectAceFlags.ObjectAceTypePresent) != System.Security.AccessControl.ObjectAceFlags.None) { for (int i = 0; i < 0x10; i++) { b[i] = binaryForm[(num + num2) + i]; } num2 += 0x10; } else { for (int j = 0; j < 0x10; j++) { b[j] = 0; } } objectAceType = new Guid(b); if ((objectFlags & System.Security.AccessControl.ObjectAceFlags.InheritedObjectAceTypePresent) != System.Security.AccessControl.ObjectAceFlags.None) { for (int k = 0; k < 0x10; k++) { b[k] = binaryForm[(num + num2) + k]; } num2 += 0x10; } else { for (int m = 0; m < 0x10; m++) { b[m] = 0; } } inheritedObjectAceType = new Guid(b); sid = new SecurityIdentifier(binaryForm, num + num2); opaque = null; int num7 = (binaryForm[offset + 3] << 8) + binaryForm[offset + 2]; if ((num7 % 4) == 0) { int num8 = (((num7 - 4) - 4) - 4) - ((byte) sid.BinaryLength); if ((objectFlags & System.Security.AccessControl.ObjectAceFlags.ObjectAceTypePresent) != System.Security.AccessControl.ObjectAceFlags.None) { num8 -= 0x10; } if ((objectFlags & System.Security.AccessControl.ObjectAceFlags.InheritedObjectAceTypePresent) != System.Security.AccessControl.ObjectAceFlags.None) { num8 -= 0x10; } if (num8 > 0) { opaque = new byte[num8]; for (int n = 0; n < num8; n++) { opaque[n] = binaryForm[((offset + num7) - num8) + n]; } } return true; } Label_0209: qualifier = AceQualifier.AccessAllowed; accessMask = 0; sid = null; objectFlags = System.Security.AccessControl.ObjectAceFlags.None; objectAceType = Guid.NewGuid(); inheritedObjectAceType = Guid.NewGuid(); isCallback = false; opaque = null; return false; }
// // 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; }
// Constructors public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, System.Security.Principal.SecurityIdentifier sid, ObjectAceFlags flags, System.Guid type, System.Guid inheritedType, bool isCallback, byte[] opaque) {}
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, System.Security.Principal.SecurityIdentifier sid, bool isCallback, byte[] opaque) : base (default(AceType), default(AceFlags), default(int), default(System.Security.Principal.SecurityIdentifier), default(byte[])) { }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque);
internal QualifiedAce(AceType type, AceFlags flags, int accessMask, SecurityIdentifier sid, byte[] opaque) : base(type, flags, accessMask, sid) { this._qualifier = this.QualifierFromType(type, out this._isCallback); this.SetOpaque(opaque); }