private SafeHGlobalBuffer CreateRelativeSecurityDescriptor()
        {
            using (var sd_buffer = CreateAbsoluteSecurityDescriptor())
            {
                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();
                }

                var relative_sd = new SafeHGlobalBuffer(total_length);
                try
                {
                    NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException();
                    return(Interlocked.Exchange(ref relative_sd, null));
                }
                finally
                {
                    relative_sd?.Close();
                }
            }
        }
Exemple #2
0
        private NtResult <SafeHGlobalBuffer> CreateRelativeSecurityDescriptor(bool throw_on_error)
        {
            using (var sd_buffer = CreateAbsoluteSecurityDescriptor(throw_on_error))
            {
                if (!sd_buffer.IsSuccess)
                {
                    return(sd_buffer);
                }

                int      total_length = 0;
                NtStatus status       = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer.Result, SafeHGlobalBuffer.Null, ref total_length);
                if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                using (var relative_sd = new SafeHGlobalBuffer(total_length))
                {
                    return(NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer.Result, relative_sd, ref total_length)
                           .CreateResult(throw_on_error, () => relative_sd.Detach()));
                }
            }
        }
Exemple #3
0
        /// <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();
            }
        }