// // Modifies the DACL // private bool ModifyAccess(AccessControlModification modification, ObjectAccessRule rule, out bool modified) { bool result = true; if (SecurityDescriptor.DiscretionaryAcl == null) { if (modification == AccessControlModification.Remove || modification == AccessControlModification.RemoveAll || modification == AccessControlModification.RemoveSpecific) { modified = false; return(result); } //_securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, GenericAcl.AclRevisionDS, 1); //_securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent); SecurityDescriptor.AddDiscretionaryAcl(GenericAcl.AclRevisionDS, 1); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset) && (rule.ObjectFlags != ObjectAceFlags.None)) { // // This will result in an object ace being added to the dacl, so the dacl revision must be AclRevisionDS // if (SecurityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS) { // // we need to create a new dacl with the same aces as the existing one but the revision should be AclRevisionDS // byte[] binaryForm = new byte[SecurityDescriptor.DiscretionaryAcl.BinaryLength]; SecurityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form SecurityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } SecurityIdentifier sid = rule.IdentityReference.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier; if (rule.AccessControlType == AccessControlType.Allow) { switch (modification) { case AccessControlModification.Add: //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Set: //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Reset: SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Remove: //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.RemoveAll: result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) { throw new InvalidOperationException(SR.InvalidOperation_RemoveFail); } break; case AccessControlModification.RemoveSpecific: //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule); break; default: throw new ArgumentOutOfRangeException( nameof(modification), SR.ArgumentOutOfRange_Enum); } } else if (rule.AccessControlType == AccessControlType.Deny) { switch (modification) { case AccessControlModification.Add: //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Set: //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Reset: SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Remove: //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.RemoveAll: result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) { throw new InvalidOperationException(SR.InvalidOperation_RemoveFail); } break; case AccessControlModification.RemoveSpecific: //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); SecurityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule); break; default: throw new ArgumentOutOfRangeException( nameof(modification), SR.ArgumentOutOfRange_Enum); } } else { throw new ArgumentException(SR.Format(SR.TypeUnrecognized_AccessControl, rule.AccessControlType)); } modified = result; AccessRulesModified |= modified; return(result); }