internal static int SetSecurityInfo(
ResourceType type,
string name,
SafeHandle handle,
SecurityInfos securityInformation,
SecurityIdentifier owner,
SecurityIdentifier group,
GenericAcl sacl,
GenericAcl dacl)
{
int errorCode;
int Length;
byte[] OwnerBinary = null, GroupBinary = null, SaclBinary = null, DaclBinary = null;
Privilege securityPrivilege = null;
if (owner != null)
{
Length = owner.BinaryLength;
OwnerBinary = new byte[Length];
owner.GetBinaryForm(OwnerBinary, 0);
}
if (group != null)
{
Length = group.BinaryLength;
GroupBinary = new byte[Length];
group.GetBinaryForm(GroupBinary, 0);
}
if (dacl != null)
{
Length = dacl.BinaryLength;
DaclBinary = new byte[Length];
dacl.GetBinaryForm(DaclBinary, 0);
}
if (sacl != null)
{
Length = sacl.BinaryLength;
SaclBinary = new byte[Length];
sacl.GetBinaryForm(SaclBinary, 0);
}
if ((securityInformation & SecurityInfos.SystemAcl) != 0)
{
//
// Enable security privilege if trying to set a SACL.
// Note: even setting it by handle needs this privilege enabled!
//
securityPrivilege = new Privilege(Privilege.Security);
}
try
{
if (securityPrivilege != null)
{
try
{
securityPrivilege.Enable();
}
catch (PrivilegeNotHeldException)
{
// we will ignore this exception and press on just in case this is a remote resource
}
}
if (name != null)
{
errorCode = (int)Interop.Advapi32.SetSecurityInfoByName(name, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
}
else if (handle != null)
{
if (handle.IsInvalid)
{
throw new ArgumentException(
SR.Argument_InvalidSafeHandle,
nameof(handle));
}
else
{
errorCode = (int)Interop.Advapi32.SetSecurityInfoByHandle(handle, (uint)type, (uint)securityInformation, OwnerBinary, GroupBinary, DaclBinary, SaclBinary);
}
}
else
{
// both are null, shouldn't happen
Debug.Assert(false, "Internal error: both name and handle are null");
throw new ArgumentException();
}
if (errorCode == Interop.Errors.ERROR_NOT_ALL_ASSIGNED ||
errorCode == Interop.Errors.ERROR_PRIVILEGE_NOT_HELD)
{
throw new PrivilegeNotHeldException(Privilege.Security);
}
else if (errorCode == Interop.Errors.ERROR_ACCESS_DENIED ||
errorCode == Interop.Errors.ERROR_CANT_OPEN_ANONYMOUS)
{
throw new UnauthorizedAccessException();
}
else if (errorCode != Interop.Errors.ERROR_SUCCESS)
{
goto Error;
}
}
catch
{
// protection against exception filter-based luring attacks
if (securityPrivilege != null)
{
securityPrivilege.Revert();
}
throw;
}
finally
{
if (securityPrivilege != null)
{
securityPrivilege.Revert();
}
}
return 0;
Error:
if (errorCode == Interop.Errors.ERROR_NOT_ENOUGH_MEMORY)
{
throw new OutOfMemoryException();
}
return errorCode;
}
}