/// <summary> /// Compares the AceObjectFlags attribute of an ACE against that of an AceAssertion. If the {@code assertionObjFlags} /// are null, a true result is returned. /// If the {@code assertionObjFlags} are not null, then either the {@code aceObjFlags} must be a match, or they /// must /// not be set. The not set case is deemed a match because MS AD documentation states that if an object type /// (referred to by the flags) is also empty, then the ACE controls the ability to perform operations of the /// given access right on all object classes. In this case, the decision about the ACE matching (regarding the /// object) /// is left up to the {@linkplain doObjectTypesMatch} and {@linkplain doInheritedObjectTypesMatch} methods. /// An ACE will appear without object flags when it is for "Full Control" permissions. /// @param aceObjFlags /// object flags from the ACE /// @param assertionObjFlags /// object flags from the AceAssertion /// @return true if match, false if not /// </summary> private bool DoObjectFlagsMatch(AceObjectFlags aceObjFlags, AceObjectFlags assertionObjFlags) { var res = true; if (assertionObjFlags != null) { if (aceObjFlags != null && (aceObjFlags.AsUInt() & assertionObjFlags.AsUInt()) == assertionObjFlags.AsUInt()) { res = true; } else if (aceObjFlags == null || aceObjFlags.AsUInt() == 0) { // MS docs state that if the object type is _not_ present - which is hinted at by presence of object flags - // then the ACE controls that right on all object classes/attributes of such objects. // So defer ultimate decision to object/inherited object type matching. res = true; } else { res = false; } } return(res); }
/// <summary> /// AceAssertion constructor /// </summary> /// <param name="aceRight"> /// A single AceRight (e.g.: use AceRights.parseValue(0x00000004) if AceRights.ObjectRight enum does not contain /// desired right.) MUST be specified. /// </param> /// <param name="aceObjFlags">One or more AceObjectFlags, may be null.</param> /// <param name="objectType">Object type GUID. Must be set if Flag.ACE_OBJECT_TYPE_PRESENT is in aceObjFlags</param> /// <param name="inheritedObjectType"> /// Inherited object type GUID. Must be set if Flag.ACE_INHERITED_OBJECT_TYPE_PRESENT is in aceObjFlags /// </param> /// <param name="requiredFlag">Single AceFlag that stipulates an ACE must contain it; may be null.</param> /// <param name="excludedFlag">Single AceFlag that stipulates an ACE must NOT contain it; may be null.</param> public AceAssertion(AceRights aceRight, AceObjectFlags aceObjFlags, Guid?objectType, Guid?inheritedObjectType, AceFlag requiredFlag, AceFlag excludedFlag) { this.aceRight = aceRight; this.aceObjectFlags = aceObjFlags; this.objectType = objectType; this.inheritedObjectType = inheritedObjectType; this.requiredFlag = requiredFlag; this.excludedFlag = excludedFlag; }
/// <summary> /// Load the ACE from the buffer returning the last ACE segment position into the buffer. /// @param buff source buffer. /// @param start start loading position. /// @return last loading position. /// </summary> public void Parse(BinaryReader buff) { var start = buff.BaseStream.Position; byte[] bytes = NumberFacility.GetBytes(buff.ReadInt32()); this.type = AceTypeExtension.ParseValue(bytes[0]); this.flags = AceFlagExtension.ParseValue(bytes[1]); int size = NumberFacility.GetInt(bytes[3], bytes[2]); this.rights = AceRights.ParseValue(NumberFacility.GetReverseInt(buff.ReadInt32())); if (this.type == AceType.AccessAllowedObjectAceType || this.type == AceType.AccessDeniedObjectAceType) { this.objectFlags = AceObjectFlags.ParseValue(NumberFacility.GetReverseInt(buff.ReadInt32())); if (this.objectFlags.GetFlags().Contains(AceObjectFlags.Flag.AceObjectTypePresent)) { this.objectType = new Guid(buff.ReadBytes(16)); } if (this.objectFlags.GetFlags().Contains(AceObjectFlags.Flag.AceInheritedObjectTypePresent)) { this.inheritedObjectType = new Guid(buff.ReadBytes(16)); } } this.sid = new SID(); this.sid.Parse(buff); if (size > 0) { var lastPos = start + size; this.applicationData = new byte[lastPos - buff.BaseStream.Position]; for (var i = 0; i < applicationData.Length; i++) { this.applicationData[i] = buff.ReadByte(); } } }
/// <summary> /// Checks whether the inherited object type identified by the ACE matches the inherited object type of the /// AceAssertion given. If the assertionObjFlags are null, or they do not specify /// ACE_INHERITED_OBJECT_TYPE_PRESENT, a true result is returned. /// @param aceInhObjectType /// byte array containing the ACE inheritedObjectType GUID /// @param assertionInhObjectType /// string containing the AceAssertion inheritedObjectType /// @param assertionObjFlags /// AceObjectFlags from the AceAssertion /// @return true if match, false if not /// </summary> private bool DoInheritedObjectTypesMatch(Guid?aceInhObjectType, Guid?assertionInhObjectType, AceObjectFlags assertionObjFlags) { if (assertionObjFlags == null) { return(true); } if ((assertionObjFlags.AsUInt() & (uint)AceObjectFlags.Flag.AceInheritedObjectTypePresent) == (uint)AceObjectFlags.Flag.AceInheritedObjectTypePresent) { if (aceInhObjectType != null && aceInhObjectType != assertionInhObjectType) { return(false); } } return(true); }
/// <summary> /// Sets object flags. /// @param objectFlags ACE object flags. /// AceObjectFlags /// </summary> public void SetObjectFlags(AceObjectFlags objectFlags) => this.objectFlags = objectFlags;