// // 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) { Debug.Assert(false, "Invalid operation"); throw new Exception(); } 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( "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) { Debug.Assert(false, "Invalid operation"); throw new Exception(); } 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( "modification", SR.ArgumentOutOfRange_Enum); } } else { Debug.Assert(false, "rule.AccessControlType unrecognized"); throw new Exception(); } modified = result; AccessRulesModified |= modified; return(result); }