// Do not use this method unless you understand the consequnces of lack of synchronization static void EditKernelObjectSecurity(SafeCloseHandle kernelObject, List <SecurityIdentifier> accounts, SecurityIdentifier account, int right, bool add) { // take the SECURITY_DESCRIPTOR from the kernelObject int lpnLengthNeeded; bool success = ListenerUnsafeNativeMethods.GetKernelObjectSecurity(kernelObject, ListenerUnsafeNativeMethods.DACL_SECURITY_INFORMATION, null, 0, out lpnLengthNeeded); if (!success) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != ListenerUnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } } byte[] pSecurityDescriptor = new byte[lpnLengthNeeded]; #pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() success = ListenerUnsafeNativeMethods.GetKernelObjectSecurity(kernelObject, ListenerUnsafeNativeMethods.DACL_SECURITY_INFORMATION, pSecurityDescriptor, pSecurityDescriptor.Length, out lpnLengthNeeded); if (!success) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception()); } CommonSecurityDescriptor securityDescriptor = new CommonSecurityDescriptor(false, false, pSecurityDescriptor, 0); DiscretionaryAcl dacl = securityDescriptor.DiscretionaryAcl; // add ACEs to the SECURITY_DESCRIPTOR of the kernelObject if (account != null) { EditDacl(dacl, account, right, add); } else if (accounts != null) { foreach (SecurityIdentifier accountInList in accounts) { EditDacl(dacl, accountInList, right, add); } } lpnLengthNeeded = securityDescriptor.BinaryLength; pSecurityDescriptor = new byte[lpnLengthNeeded]; securityDescriptor.GetBinaryForm(pSecurityDescriptor, 0); // set the SECURITY_DESCRIPTOR on the kernelObject #pragma warning suppress 56523 // Microsoft, Win32Exception ctor calls Marshal.GetLastWin32Error() success = ListenerUnsafeNativeMethods.SetKernelObjectSecurity(kernelObject, ListenerUnsafeNativeMethods.DACL_SECURITY_INFORMATION, pSecurityDescriptor); if (!success) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception()); } }
private static void EditKernelObjectSecurity(SafeCloseHandle kernelObject, List <SecurityIdentifier> accounts, SecurityIdentifier account, int right, bool add) { int num; if (!ListenerUnsafeNativeMethods.GetKernelObjectSecurity(kernelObject, 4, null, 0, out num)) { int error = Marshal.GetLastWin32Error(); if (error != 0x7a) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } } byte[] pSecurityDescriptor = new byte[num]; if (!ListenerUnsafeNativeMethods.GetKernelObjectSecurity(kernelObject, 4, pSecurityDescriptor, pSecurityDescriptor.Length, out num)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception()); } CommonSecurityDescriptor descriptor = new CommonSecurityDescriptor(false, false, pSecurityDescriptor, 0); DiscretionaryAcl discretionaryAcl = descriptor.DiscretionaryAcl; if (account != null) { EditDacl(discretionaryAcl, account, right, add); } else if (accounts != null) { foreach (SecurityIdentifier identifier in accounts) { EditDacl(discretionaryAcl, identifier, right, add); } } pSecurityDescriptor = new byte[descriptor.BinaryLength]; descriptor.GetBinaryForm(pSecurityDescriptor, 0); if (!ListenerUnsafeNativeMethods.SetKernelObjectSecurity(kernelObject, 4, pSecurityDescriptor)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception()); } }