//
// 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);
}