public KnownAce(AceType type, AceFlags flags, int mask, Sid sid) { if ( type != AceType.AccessAllowed && type != AceType.AccessDenied && type != AceType.SystemAlarm && type != AceType.SystemAudit ) throw new ArgumentException("Invalid ACE type."); this.MemoryRegion = new MemoryAlloc( Marshal.SizeOf(typeof(KnownAceStruct)) - // known ace struct size sizeof(int) + // minus SidStart field sid.Length // plus SID length ); KnownAceStruct knownAce = new KnownAceStruct(); // Initialize the ACE (minus the SID). knownAce.Header.AceType = type; knownAce.Header.AceFlags = flags; knownAce.Header.AceSize = (ushort)this.MemoryRegion.Size; knownAce.Mask = mask; // Write the ACE to memory. this.MemoryRegion.WriteStruct<KnownAceStruct>(knownAce); // Write the SID. this.MemoryRegion.WriteMemory(Win32.KnownAceSidStartOffset.ToInt32(), sid, 0, sid.Length); // Update the cached info. this.Read(); }
internal CommonAce (AceType type, AceFlags flags, int accessMask, SecurityIdentifier sid, byte[] opaque) : base(type, flags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
// 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. }
// Constructor. internal KnownAce(AceFlags aceFlags, AceType aceType, int accessMask, SecurityIdentifier securityIdentifier) : base(aceFlags, aceType) { this.accessMask = accessMask; this.securityIdentifier = securityIdentifier; }
public KnownAce(AceType type, AceFlags flags, int mask, Sid sid) { if ( type != AceType.AccessAllowed && type != AceType.AccessDenied && type != AceType.SystemAlarm && type != AceType.SystemAudit ) throw new ArgumentException("Invalid ACE type."); this.MemoryRegion = new MemoryAlloc( Marshal.SizeOf(typeof(KnownAceStruct)) - sizeof(int) + sid.Length ); KnownAceStruct knownAce = new KnownAceStruct(); knownAce.Header.AceType = type; knownAce.Header.AceFlags = flags; knownAce.Header.AceSize = (ushort)this.MemoryRegion.Size; knownAce.Mask = mask; this.MemoryRegion.WriteStruct<KnownAceStruct>(knownAce); this.MemoryRegion.WriteMemory(Win32.KnownAceSidStartOffset.ToInt32(), sid, 0, sid.Length); this.Read(); }
public CompoundAce (AceFlags flags, int accessMask, CompoundAceType compoundAceType, SecurityIdentifier sid) : base (AceType.AccessAllowedCompound, flags) { this.compound_ace_type = compoundAceType; this.AccessMask = accessMask; this.SecurityIdentifier = sid; }
public CustomAce (AceType type, AceFlags flags, byte[] opaque) : base(type, flags) { /* FIXME: check length of opaque > * MaxOpaqueLength or !multiple of 4 */ SetOpaque (opaque); }
public CompoundAce (AceFlags flags, int accessMask, CompoundAceType compoundAceType, SecurityIdentifier sid) : base (InheritanceFlags.None, PropagationFlags.None) { this.compound_ace_type = compoundAceType; this.AceFlags = flags; this.AccessMask = accessMask; this.SecurityIdentifier = sid; }
public CustomAce(AceType type, AceFlags flags, byte[] opaque) : base(type, flags) { if (type <= AceType.SystemAlarmCallbackObject) { throw new ArgumentOutOfRangeException("type", Environment.GetResourceString("ArgumentOutOfRange_InvalidUserDefinedAceType")); } this.SetOpaque(opaque); }
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; }
internal KnownAce(AceType type, AceFlags flags, int accessMask, System.Security.Principal.SecurityIdentifier securityIdentifier) : base(type, flags) { if (securityIdentifier == null) { throw new ArgumentNullException("securityIdentifier"); } this.AccessMask = accessMask; this.SecurityIdentifier = securityIdentifier; }
internal GenericAce (AceType type, AceFlags flags) { if (type > AceType.MaxDefinedAceType) { throw new ArgumentOutOfRangeException ("type"); } this.ace_type = type; this.ace_flags = flags; }
public CommonAce (AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque) : base(ConvertType (qualifier, isCallback), flags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; }
// 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; }
internal GenericAce(byte[] binaryForm, int offset) { if (binaryForm == null) throw new ArgumentNullException("binaryForm"); if (offset < 0 || offset > binaryForm.Length - 2) throw new ArgumentOutOfRangeException("offset", offset, "Offset out of range"); ace_type = (AceType)binaryForm[offset]; ace_flags = (AceFlags)binaryForm[offset + 1]; }
internal ObjectAce (AceType type, AceFlags flags, int accessMask, SecurityIdentifier sid, ObjectAceFlags objFlags, Guid objType, Guid inheritedType, byte[] opaque) : base(type, flags, opaque) { AccessMask = accessMask; SecurityIdentifier = sid; ObjectAceFlags = objFlags; ObjectAceType = objType; InheritedObjectAceType = inheritedType; }
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); }
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 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(); }
/// <summary> /// Get hash code. /// </summary> /// <returns>The hash code</returns> public override int GetHashCode() { return(AceType.GetHashCode() ^ AceFlags.GetHashCode() ^ Mask.GetHashCode() ^ Sid.GetHashCode() ^ ObjectType.GetHashCode() ^ InheritedObjectType.GetHashCode()); }
/// <summary> /// Add an access allowed ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessAllowedAce(uint mask, AceFlags flags, Sid sid) { Add(new Ace(AceType.Allowed, flags, mask, sid)); }
/// <summary> /// Add an access allowed ACE to the DACL /// </summary> /// <param name="mask">The access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The SID</param> public void AddAccessAllowedAce(AccessMask mask, AceFlags flags, Sid sid) { AddAccessAllowedAceInternal(mask, AceFlags.None, sid); }
private void AddAccessDeniedAceInternal(AccessMask mask, AceFlags flags, string sid) { AddAce(AceType.Denied, mask, flags, NtSecurity.SidFromSddl(sid)); }
/// <summary> /// Constructor /// </summary> /// <param name="type">ACE type</param> /// <param name="flags">ACE flags</param> /// <param name="mask">ACE access mask</param> /// <param name="sid">ACE sid</param> public Ace(AceType type, AceFlags flags, GenericAccessRights mask, Sid sid) : this(type, flags, (uint)mask, sid) { }
public static void AdditionalTestCases() { bool isContainer = false; bool isDS = false; RawAcl rawAcl = null; SystemAcl sAcl = 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 = "BA"; //CommonAce constructor additional parameters AceQualifier aceQualifier = 0; //ObjectAce constructor additional parameters ObjectAceFlags objectAceFlag = 0; Guid objectAceType; Guid inheritedObjectAceType; //case 1, an SystemAudit ACE with a zero access mask is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); gAce = new CommonAce(AceFlags.AuditFlags, AceQualifier.SystemAudit, 0, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //the only ACE is a meaningless ACE, will be removed //drop the ace from the rawAcl rawAcl.RemoveAce(0); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 2, an inherit-only SystemAudit ACE on an object ACL is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); gAce = new CommonAce(AceFlags.InheritanceFlags | AceFlags.AuditFlags, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //the only ACE is a meaningless ACE, will be removed rawAcl.RemoveAce(0); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 3, an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object is meaningless, will be removed revision = 0; capacity = 1; rawAcl = new RawAcl(revision, capacity); //200 has inheritOnly, SuccessfulAccess and FailedAccess gAce = new CommonAce((AceFlags)200, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //the only ACE is a meaningless ACE, will be removed rawAcl.RemoveAce(0); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 4, a SystemAudit ACE without Success or Failure Flags is meaningless, will be removed revision = 255; capacity = 1; rawAcl = new RawAcl(revision, capacity); gAce = new CommonAce(AceFlags.None, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)), false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //audit ACE does not specify either Success or Failure Flags is removed rawAcl.RemoveAce(0); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 5, a CustomAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceType = AceType.MaxDefinedAceType + 1; aceFlag = AceFlags.AuditFlags; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl)); //case 6, a CompoundAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceFlag = AceFlags.AuditFlags; accessMask = 1; compoundAceType = CompoundAceType.Impersonation; gAce = new CompoundAce(aceFlag, accessMask, compoundAceType, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid))); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl)); //case 7, a ObjectAce revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceFlag = AceFlags.InheritanceFlags | AceFlags.AuditFlags; aceQualifier = AceQualifier.SystemAudit; 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; sAcl = new SystemAcl(isContainer, isDS, rawAcl); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 8, no Ace revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); isContainer = true; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); Assert.True(TestConstructor(sAcl, isContainer, isDS, true, rawAcl)); //case 9, Aces from case 1 to 7 revision = 127; capacity = 5; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid)).ToString(); rawAcl = new RawAcl(revision, capacity); //an SystemAudit ACE with a zero access mask //is meaningless, will be removed gAce = new CommonAce(AceFlags.AuditFlags, AceQualifier.SystemAudit, 0, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 1.ToString()), false, null); rawAcl.InsertAce(rawAcl.Count, gAce); //an inherit-only SystemAudit ACE without ContainerInherit or ObjectInherit flags on a container object //is meaningless, will be removed //200 has inheritOnly, SuccessfulAccess and FailedAccess gAce = new CommonAce((AceFlags)200, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 2.ToString()), false, null); rawAcl.InsertAce(rawAcl.Count, gAce); //a SystemAudit ACE without Success or Failure Flags //is meaningless, will be removed gAce = new CommonAce(AceFlags.None, AceQualifier.SystemAudit, 1, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 3.ToString()), false, null); rawAcl.InsertAce(rawAcl.Count, gAce); //a ObjectAce aceFlag = AceFlags.InheritanceFlags | AceFlags.AuditFlags; aceQualifier = AceQualifier.SystemAudit; 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) + 4.ToString()), objectAceFlag, objectAceType, inheritedObjectAceType, false, null); rawAcl.InsertAce(rawAcl.Count, gAce); // a CustomAce gAce = new CustomAce(AceType.MaxDefinedAceType + 1, AceFlags.AuditFlags, null); rawAcl.InsertAce(rawAcl.Count, gAce); //a CompoundAce gAce = new CompoundAce(AceFlags.AuditFlags, 1, CompoundAceType.Impersonation, new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sid) + 5.ToString())); rawAcl.InsertAce(rawAcl.Count, gAce); isContainer = true; isDS = false; sAcl = new SystemAcl(isContainer, isDS, rawAcl); //the first 3 Aces will be removed by SystemAcl constructor rawAcl.RemoveAce(0); rawAcl.RemoveAce(0); rawAcl.RemoveAce(0); //Mark changed design to make ACL with any CustomAce, CompoundAce uncanonical Assert.True(TestConstructor(sAcl, isContainer, isDS, false, rawAcl)); }
/// <summary> /// Add an access allowed ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessAllowedAce(GenericAccessRights mask, AceFlags flags, string sid) { AddAccessAllowedAce((uint)mask, flags, sid); }
public HResult MapGeneric(ref Guid ObjectType, ref AceFlags AceFlags, ref int Mask) { return(HResult.OK); }
/// <summary> /// Add mandatory integrity label to SACL /// </summary> /// <param name="label">The integrity label SID</param> /// <param name="flags">The ACE flags.</param> /// <param name="policy">The mandatory label policy</param> public void AddMandatoryLabel(Sid label, AceFlags flags, MandatoryLabelPolicy policy) { MandatoryLabel = new Ace(AceType.MandatoryLabel, flags, policy, label); }
/// <summary> /// Add mandatory integrity label to SACL /// </summary> /// <param name="level">The integrity level</param> /// <param name="flags">The ACE flags.</param> /// <param name="policy">The mandatory label policy</param> public void AddMandatoryLabel(TokenIntegrityLevel level, AceFlags flags, MandatoryLabelPolicy policy) { AddMandatoryLabel(NtSecurity.GetIntegritySid(level), flags, policy); }
/// <summary> /// Add an access denied ACE to the DACL /// </summary> /// <param name="mask">The access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The SID</param> public void AddAccessDeniedAce(AccessMask mask, AceFlags flags, Sid sid) { AddAccessDeniedAceInternal(mask, flags, sid); }
private void AddAce(AceType type, AccessMask mask, AceFlags flags, Sid sid) { AddAce(new Ace(type, flags, mask, sid)); }
private void AddAccessDeniedAceInternal(AccessMask mask, AceFlags flags, Sid sid) { AddAce(AceType.Denied, mask, flags, sid); }
// // 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 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); }
// FUNCTION: AddAccessRights // // PURPOSE: Applies ACE for access to specified object DACL // // RETURN VALUE: true or false // // COMMENTS: unsafe static bool AddAccessRights(string szPrinterName, uint dwAccessMask, AceFlags bAceFlags, string szUserName, byte bType) { // ACL variables ACL_SIZE_INFORMATION?AclInfo = null; uint dwNewAceCount = 0; // New ACL variables int dwNewACLSize; // Temporary ACE ACCESS_ALLOWED_ACE *pTempAce; // structure is same for access denied ace uint CurrentAceIndex; try { // Call LookupAccountName if (!LookupAccountName(null, szUserName, out var pSid, out var szDomainName, out var SidType)) { Console.WriteLine("Error {0} - LookupAccountName", Win32Error.GetLastError()); return(false); } Console.Write("Adding ACE for {0}\n", szUserName); // Get security DACL for printer if (!GetPrinterDACL(szPrinterName, out var pACL)) { Console.Write("Error {0} getting printer DACL\n", Win32Error.GetLastError()); return(false); } // Compute size needed for the new ACL using (pACL) { if (!pACL.IsInvalid) // Get size of old ACL { AclInfo = ((PACL)pACL).GetAclInformation <ACL_SIZE_INFORMATION>(); } if (!pACL.IsInvalid) // Add room for new ACEs { dwNewACLSize = (int)AclInfo.Value.AclBytesInUse + Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + GetLengthSid(pSid) - sizeof(uint); } else { dwNewACLSize = Marshal.SizeOf(typeof(ACCESS_ALLOWED_ACE)) + Marshal.SizeOf(typeof(ACL)) + GetLengthSid(pSid) - sizeof(uint); } } // Allocate and setup ACL. using var pNewACL = new SafePACL(dwNewACLSize); if (pNewACL.IsInvalid) { Console.Write("LocalAlloc failed.\n"); throw new Exception(); } // If new ACE is Access Denied ACE add it to front of new ACL if (bType == ACCESS_DENY) { // Add the access-denied ACE to the new DACL if (!AddAccessDeniedAce(pNewACL, 2, dwAccessMask, pSid)) { Console.Write("Error %d: AddAccessDeniedAce\n", Win32Error.GetLastError()); throw new Exception(); } dwNewAceCount++; // get pointer to ace we just added, so we can change the AceFlags if (!GetAce(pNewACL, 0, out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); pTempAce->Header.AceFlags = bAceFlags; } // If a DACL was present, copy the resident ACEs to the new DACL if (!pACL.IsInvalid) { // Copy the file's old ACEs to our new ACL if (AclInfo.Value.AceCount > 0) { for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.Value.AceCount; CurrentAceIndex++) { // Get an ACE if (!GetAce(pACL, CurrentAceIndex, out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); // Check to see if this ACE is identical to one were adding. If it is identical don't copy it over. if (!EqualSid((IntPtr)(void *)&(pTempAce->SidStart), pSid) || (pTempAce->Mask != dwAccessMask) || (pTempAce->Header.AceFlags != bAceFlags)) { // ACE is distinct, add it to the new ACL if (!AddAce(pNewACL, 2, uint.MaxValue, (IntPtr)pTempAce, ((ACE_HEADER *)pTempAce)->AceSize)) { Console.Write("Error %d: AddAce\n", Win32Error.GetLastError()); throw new Exception(); } dwNewAceCount++; } } } } // If the new ACE is an Access allowed ACE add it at the end. if (bType == ACCESS_ALLOW) { // Add the access-allowed ACE to the new DACL if (!AddAccessAllowedAce(pNewACL, 2, dwAccessMask, pSid)) { Console.Write("Error %d: AddAccessAllowedAce\n", Win32Error.GetLastError()); throw new Exception(); } // Get pointer to ACE we just added, so we can change the AceFlags if (!GetAce(pNewACL, dwNewAceCount, // Zero based position of the last ace out var mTempAce)) { Console.Write("Error %d: GetAce\n", Win32Error.GetLastError()); throw new Exception(); } pTempAce = (ACCESS_ALLOWED_ACE *)(void *)mTempAce.DangerousGetHandle(); pTempAce->Header.AceFlags = bAceFlags; } // Set the DACL to the object if (!SetPrinterDACL(szPrinterName, pNewACL)) { Console.Write("Error %d setting printer DACL\n", Win32Error.GetLastError()); throw new Exception(); } } finally { } return(true); }
public static void BasicValidationTestCases() { bool isContainer = false; bool isDS = false; RawAcl rawAcl = null; SystemAcl systemAcl = 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 = "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; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 0; sidStr = "BG"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); Assert.True(TestPurge(systemAcl, 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 inheritedonly and inherited gAce = new CommonAce((AceFlags)199, AceQualifier.SystemAudit, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(systemAcl, 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.SystemAudit, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 1; sidStr = "BA"; sid = new SecurityIdentifier(Utils.TranslateStringConstFormatSidToStandardFormatSid(sidStr)); Assert.True(TestPurge(systemAcl, 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.SystemAudit, 1, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 1; Assert.True(TestPurge(systemAcl, 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)199, AceQualifier.SystemAudit, 1, sid, false, null); rawAcl.InsertAce(0, gAce); //215 has all aceflags but inheritedonly gAce = new CommonAce((AceFlags)215, AceQualifier.SystemAudit, 2, sid, false, null); rawAcl.InsertAce(1, gAce); isContainer = true; isDS = false; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 1; Assert.True(TestPurge(systemAcl, 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)); gAce = new CommonAce(AceFlags.FailedAccess, AceQualifier.SystemAudit, 1, sid, false, null); rawAcl.InsertAce(0, gAce); gAce = new CommonAce(AceFlags.SuccessfulAccess, AceQualifier.SystemAudit, 2, sid, false, null); rawAcl.InsertAce(0, gAce); isContainer = true; isDS = false; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(systemAcl, sid, 0)); //case 7, 1 explicit CustomAce Assert.Throws <InvalidOperationException>(() => { revision = 127; capacity = 1; rawAcl = new RawAcl(revision, capacity); aceType = AceType.MaxDefinedAceType + 1; //199 has all aceflags but inheritedonly and inherited aceFlag = (AceFlags)199; opaque = null; gAce = new CustomAce(aceType, aceFlag, opaque); rawAcl.InsertAce(0, gAce); isContainer = false; isDS = false; systemAcl = new SystemAcl(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 TestPurge(systemAcl, sid, aceCount); }); //case 8, 1 explicit CompoundAce Assert.Throws <InvalidOperationException>(() => { 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; systemAcl = new SystemAcl(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 TestPurge(systemAcl, 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.SystemAudit; 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; systemAcl = new SystemAcl(isContainer, isDS, rawAcl); aceCount = 0; Assert.True(TestPurge(systemAcl, sid, aceCount)); }
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); }
private static bool RemoveInheritanceBits(AceFlags existing, AceFlags remove, bool isDS, out AceFlags result, out bool total) { result = AceFlags.None; total = false; AF af = AFFromAceFlags(existing, isDS); AF af2 = AFFromAceFlags(remove, isDS); PM pm = AFtoPM[(int)af]; PM pm2 = AFtoPM[(int)af2]; if ((pm == PM.GO) || (pm2 == PM.GO)) { return(false); } PM pm3 = pm & ~pm2; if (pm3 == 0) { total = true; return(true); } AF af3 = PMtoAF[(int)pm3]; if (af3 == AF.Invalid) { return(false); } result = AceFlagsFromAF(af3, isDS); return(true); }
/// <summary> /// Add an access allowed ACE to the DACL /// </summary> /// <param name="mask">The access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The SID in SDDL form</param> public void AddAccessAllowedAce(AccessMask mask, AceFlags flags, string sid) { AddAccessAllowedAceInternal(mask, flags, sid); }
// // Canonicalizes AceFlags into a form that the mapping tables understand // private static AF AFFromAceFlags( AceFlags aceFlags, bool isDS ) { AF af = 0; if (( aceFlags & AceFlags.ContainerInherit ) != 0) { af |= AF.CI; } // // ObjectInherit applies only to regular aces not object aces // so it can be ignored in the object aces case // if (( !isDS ) && (( aceFlags & AceFlags.ObjectInherit ) != 0 )) { af |= AF.OI; } if (( aceFlags & AceFlags.InheritOnly ) != 0 ) { af |= AF.IO; } if (( aceFlags & AceFlags.NoPropagateInherit ) != 0 ) { af |= AF.NP; } return af; }
/// <summary> /// Add an access denied ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessDeniedAce(GenericAccessRights mask, AceFlags flags, Sid sid) { AddAccessDeniedAce((uint)mask, flags, sid); }
private static bool RemoveInheritanceBits( AceFlags existing, AceFlags remove, bool isDS, out AceFlags result, out bool total ) { result = 0; total = false; AF leftAF = AFFromAceFlags( existing, isDS ); AF rightAF = AFFromAceFlags( remove, isDS ); PM leftPM = AFtoPM[( int )leftAF]; PM rightPM = AFtoPM[( int )rightAF]; if ( leftPM == PM.Invalid || rightPM == PM.Invalid ) { return false; // incorrect ACE flags? } PM resultPM; unchecked { resultPM = leftPM & ~rightPM; } // // If the resulting propagation matrix is zero, // communicate back the fact that removal is "total" // if ( resultPM == 0 ) { total = true; return true; } AF resultAF = PMtoAF[( int )resultPM]; if ( resultAF == AF.Invalid ) { return false; } else { result = AceFlagsFromAF( resultAF, isDS ); return true; } }
public CommonAce(AceFlags flags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, bool isCallback, byte[] opaque);
private static bool MergeInheritanceBits(AceFlags left, AceFlags right, bool isDS, out AceFlags result) { result = AceFlags.None; AF af = AFFromAceFlags(left, isDS); AF af2 = AFFromAceFlags(right, isDS); PM pm = AFtoPM[(int)af]; PM pm2 = AFtoPM[(int)af2]; if ((pm == PM.GO) || (pm2 == PM.GO)) { return(false); } PM pm3 = pm | pm2; AF af3 = PMtoAF[(int)pm3]; if (af3 == AF.Invalid) { return(false); } result = AceFlagsFromAF(af3, isDS); return(true); }
public CustomAce(AceType type, AceFlags flags, byte[] opaque);
/// <summary> /// Add an access denied ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessDeniedAce(AccessMask mask, AceFlags flags, string sid) { Add(new Ace(AceType.Denied, flags, mask, new Sid(sid))); }
/// <summary> /// Add an access allowed ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessAllowedAce(uint mask, AceFlags flags, string sid) { Add(new Ace(AceType.Allowed, flags, mask, new Sid(sid))); }
// // 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> /// Add an access denied ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAccessDeniedAce(AccessMask mask, AceFlags flags, Sid sid) { Add(new Ace(AceType.Denied, flags, mask, sid)); }
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(); }
/// <summary> /// Add an audit ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAuditAce(AccessMask mask, AceFlags flags, string sid) { Add(new Ace(AceType.Audit, flags, mask, new Sid(sid))); }
// // Implements the merge of inheritance bits during the 'ADD' operation // private static bool MergeInheritanceBits( AceFlags left, AceFlags right, bool isDS, out AceFlags result ) { result = 0; AF leftAF = AFFromAceFlags( left, isDS ); AF rightAF = AFFromAceFlags( right, isDS ); PM leftPM = AFtoPM[(int)leftAF]; PM rightPM = AFtoPM[(int)rightAF]; if ( leftPM == PM.Invalid || rightPM == PM.Invalid ) { return false; // incorrect ACE flags? } PM resultPM = leftPM | rightPM; AF resultAF = PMtoAF[( int )resultPM]; if ( resultAF == AF.Invalid ) { return false; } else { result = AceFlagsFromAF( resultAF, isDS ); return true; } }
/// <summary> /// Add an audit ace to the ACL /// </summary> /// <param name="mask">The ACE access mask</param> /// <param name="flags">The ACE flags</param> /// <param name="sid">The ACE SID</param> public void AddAuditAce(AccessMask mask, AceFlags flags, Sid sid) { Add(new Ace(AceType.Audit, flags, mask, sid)); }
// 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 CompoundAce(AceFlags flags, int accessMask, CompoundAceType compoundAceType, System.Security.Principal.SecurityIdentifier sid) : base(default(AceType), default(AceFlags), default(int), default(System.Security.Principal.SecurityIdentifier)) { }
public CompoundAce(AceFlags flags, int accessMask, CompoundAceType compoundAceType, SecurityIdentifier sid);
/// <summary> /// Create a new Ace given a Sid, an access type and an set of flags /// </summary> /// <param name="sid">The sid (must be valid)</param> /// <param name="accessMask">The access accessMask</param> /// <param name="flags">The list of flags</param> public AceAccessAllowed(Sid sid, AccessType accessType, AceFlags flags) : base(sid, flags, accessType, true) { }
public ObjectAce(AceFlags aceFlags, AceQualifier qualifier, int accessMask, SecurityIdentifier sid, ObjectAceFlags flags, Guid type, Guid inheritedType, bool isCallback, byte[] opaque);
public AceAccessDenied(Sid sid, AccessType accessType, AceFlags flags) : base(sid, flags, accessType, false) { }