private static string GetFileSDDL( string filePath, NativeMethods.SECURITY_INFORMATION securityInfo) { filePath = LongPath.ToUncPath(filePath); // Note: to get the SACL, special permissions are needed. Refer https://docs.microsoft.com/en-us/windows/win32/api/aclapi/nf-aclapi-getsecurityinfo IntPtr pZero = IntPtr.Zero; IntPtr pSid = pZero; IntPtr psd = pZero; uint errorReturn = NativeMethods.GetNamedSecurityInfoW( filePath, NativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, out pSid, out pZero, out pZero, out pZero, out psd); #if !DMLIB_TEST if (errorReturn == NativeMethods.ERROR_PRIVILEGE_NOT_HELD) { throw new TransferException( string.Format( CultureInfo.CurrentCulture, Resources.PrivilegeRequiredException, NativeMethods.SACLPrivilegeName)); } else if (errorReturn != 0) { throw new Win32Exception((int)errorReturn); } #else if (errorReturn != 0) { throw new Win32Exception((int)errorReturn); } #endif try { IntPtr sdString = IntPtr.Zero; UIntPtr sd_string_size_ptr = new UIntPtr(); bool success = NativeMethods.ConvertSecurityDescriptorToStringSecurityDescriptor(psd, NativeMethods.SDDL_REVISION_1, securityInfo, out sdString, out sd_string_size_ptr); try { return(Marshal.PtrToStringAuto(sdString)); } finally { Marshal.FreeHGlobal(sdString); } } finally { NativeMethods.LocalFree(psd); } }
internal static void SetSecurityInfo(SafeHandle handle, NativeMethods.SE_OBJECT_TYPE objectType, NativeObjectSecurity fileSecurity) { byte[] managedDescriptor = fileSecurity.GetSecurityDescriptorBinaryForm(); using (SafeGlobalMemoryBufferHandle hDescriptor = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length)) { hDescriptor.CopyFrom(managedDescriptor, 0, managedDescriptor.Length); NativeMethods.SECURITY_DESCRIPTOR_CONTROL control; uint revision; if (!NativeMethods.GetSecurityDescriptorControl(hDescriptor, out control, out revision)) { NativeError.ThrowException(); } IntPtr pDacl; bool daclDefaulted, daclPresent; if (!NativeMethods.GetSecurityDescriptorDacl(hDescriptor, out daclPresent, out pDacl, out daclDefaulted)) { NativeError.ThrowException(); } IntPtr pSacl; bool saclDefaulted, saclPresent; if (!NativeMethods.GetSecurityDescriptorSacl(hDescriptor, out saclPresent, out pSacl, out saclDefaulted)) { NativeError.ThrowException(); } IntPtr pOwner; bool ownerDefaulted; if (!NativeMethods.GetSecurityDescriptorOwner(hDescriptor, out pOwner, out ownerDefaulted)) { NativeError.ThrowException(); } IntPtr pGroup; bool GroupDefaulted; if (!NativeMethods.GetSecurityDescriptorGroup(hDescriptor, out pGroup, out GroupDefaulted)) { NativeError.ThrowException(); } PrivilegeEnabler privilegeEnabler = null; try { NativeMethods.SECURITY_INFORMATION info = 0; if (daclPresent) { info |= NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION; if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0) { info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION; } else { info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION; } } if (saclPresent) { info |= NativeMethods.SECURITY_INFORMATION.SACL_SECURITY_INFORMATION; if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0) { info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION; } else { info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION; } privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } if (pOwner != IntPtr.Zero) { info |= NativeMethods.SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION; } if (pGroup != IntPtr.Zero) { info |= NativeMethods.SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION; } uint errorCode = NativeMethods.SetSecurityInfo(handle, objectType, info, pOwner, pGroup, pDacl, pSacl); if (errorCode != 0) { NativeError.ThrowException((int)errorCode); } } finally { if (privilegeEnabler != null) { privilegeEnabler.Dispose(); } } } }
static internal extern bool SetFileSecurityW(string lpFileName, NativeMethods.SECURITY_INFORMATION SecurityInformation, SafeHandle pSecurityDescriptor);