private SafeHGlobalBuffer CreateAbsoluteSecurityDescriptor() { SafeStructureInOutBuffer <SecurityDescriptorStructure> sd_buffer = null; try { byte[] dacl = Dacl?.ToByteArray(); byte[] sacl = Sacl?.ToByteArray(); byte[] owner = Owner?.Sid.ToArray(); byte[] group = Group?.Sid.ToArray(); int total_size = GetLength(dacl) + GetLength(sacl) + GetLength(owner) + GetLength(group); sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(total_size, true); NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException(); SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask; NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException(); int current_ofs = 0; if (Dacl != null) { IntPtr ptr = UpdateBuffer(sd_buffer, Dacl.NullAcl ? null : dacl, ref current_ofs); NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, ptr, Dacl.Defaulted).ToNtException(); } if (Sacl != null) { IntPtr ptr = UpdateBuffer(sd_buffer, Sacl.NullAcl ? null : sacl, ref current_ofs); NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, ptr, Sacl.Defaulted).ToNtException(); } if (Owner != null) { IntPtr ptr = UpdateBuffer(sd_buffer, owner, ref current_ofs); NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, ptr, Owner.Defaulted); } if (Group != null) { IntPtr ptr = UpdateBuffer(sd_buffer, group, ref current_ofs); NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, ptr, Group.Defaulted); } return(Interlocked.Exchange(ref sd_buffer, null)); } finally { sd_buffer?.Close(); } }
/// <summary> /// Convert security descriptor to a byte array /// </summary> /// <returns>The binary security descriptor</returns> public byte[] ToByteArray() { SafeStructureInOutBuffer <SecurityDescriptorStructure> sd_buffer = null; SafeHGlobalBuffer dacl_buffer = null; SafeHGlobalBuffer sacl_buffer = null; SafeSidBufferHandle owner_buffer = null; SafeSidBufferHandle group_buffer = null; try { sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(); NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException(); SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask; NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException(); if (Dacl != null) { if (!Dacl.NullAcl) { dacl_buffer = new SafeHGlobalBuffer(Dacl.ToByteArray()); } else { dacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, dacl_buffer.DangerousGetHandle(), Dacl.Defaulted).ToNtException(); } if (Sacl != null) { if (!Sacl.NullAcl) { sacl_buffer = new SafeHGlobalBuffer(Sacl.ToByteArray()); } else { sacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false); } NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, sacl_buffer.DangerousGetHandle(), Sacl.Defaulted).ToNtException(); } if (Owner != null) { owner_buffer = Owner.Sid.ToSafeBuffer(); NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, owner_buffer.DangerousGetHandle(), Owner.Defaulted); } if (Group != null) { group_buffer = Group.Sid.ToSafeBuffer(); NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, group_buffer.DangerousGetHandle(), Group.Defaulted); } int total_length = 0; NtStatus status = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length); if (status != NtStatus.STATUS_BUFFER_TOO_SMALL) { status.ToNtException(); } using (SafeHGlobalBuffer relative_sd = new SafeHGlobalBuffer(total_length)) { NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException(); return(relative_sd.ToArray()); } } finally { sd_buffer?.Close(); dacl_buffer?.Close(); sacl_buffer?.Close(); owner_buffer?.Close(); group_buffer?.Close(); } }
private NtResult <SafeHGlobalBuffer> CreateAbsoluteSecurityDescriptor(bool throw_on_error) { byte[] dacl = Dacl?.ToByteArray(); byte[] sacl = Sacl?.ToByteArray(); byte[] owner = Owner?.Sid.ToArray(); byte[] group = Group?.Sid.ToArray(); int total_size = GetLength(dacl) + GetLength(sacl) + GetLength(owner) + GetLength(group); using (var sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(total_size, true)) { NtStatus status = NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask; status = NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } int current_ofs = 0; if (Dacl != null) { IntPtr ptr = UpdateBuffer(sd_buffer, Dacl.NullAcl ? null : dacl, ref current_ofs); status = NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, ptr, Dacl.Defaulted); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } } if (Sacl != null) { IntPtr ptr = UpdateBuffer(sd_buffer, Sacl.NullAcl ? null : sacl, ref current_ofs); status = NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, ptr, Sacl.Defaulted); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } } if (Owner != null) { IntPtr ptr = UpdateBuffer(sd_buffer, owner, ref current_ofs); status = NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, ptr, Owner.Defaulted); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } } if (Group != null) { IntPtr ptr = UpdateBuffer(sd_buffer, group, ref current_ofs); status = NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, ptr, Group.Defaulted); if (!status.IsSuccess()) { return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error)); } } return(status.CreateResult <SafeHGlobalBuffer>(throw_on_error, () => sd_buffer.Detach())); } }