public static void SetFileSecurity(string filePath, string portableSDDL, PreserveSMBPermissions preserveSMBPermissions) { if (PreserveSMBPermissions.None == preserveSMBPermissions) { return; } if (string.IsNullOrEmpty(portableSDDL)) { return; } IntPtr pSecurityDescriptor = new IntPtr(); UIntPtr securityDescriptorLength = new UIntPtr(); if (!FileSecurityNativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptor(portableSDDL, FileSecurityNativeMethods.SDDL_REVISION_1, out pSecurityDescriptor, out securityDescriptorLength)) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } try { FileSecurityNativeMethods.SetFileSecurity(filePath, (int)(ToSecurityInfo(preserveSMBPermissions)), pSecurityDescriptor); int errorCode = Marshal.GetLastWin32Error(); int hresult = Marshal.GetHRForLastWin32Error(); if ((errorCode == FileSecurityNativeMethods.ERROR_PRIVILEGE_NOT_HELD) || (errorCode == FileSecurityNativeMethods.ERROR_ACCESS_DENIED) || (errorCode == FileSecurityNativeMethods.ERROR_INVALID_OWNER)) { throw new Win32Exception(errorCode); } if (errorCode != 0) { Marshal.ThrowExceptionForHR(hresult); } } finally { FileSecurityNativeMethods.LocalFree(pSecurityDescriptor); } }
private static string GetFileSDDL( string filePath, FileSecurityNativeMethods.SECURITY_INFORMATION securityInfo) { // 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 = FileSecurityNativeMethods.GetNamedSecurityInfoW( filePath, FileSecurityNativeMethods.SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, out pSid, out pZero, out pZero, out pZero, out psd); if (errorReturn != 0) { throw new Win32Exception((int)errorReturn); } try { IntPtr sdString = IntPtr.Zero; UIntPtr sd_string_size_ptr = new UIntPtr(); bool success = FileSecurityNativeMethods.ConvertSecurityDescriptorToStringSecurityDescriptor(psd, FileSecurityNativeMethods.SDDL_REVISION_1, securityInfo, out sdString, out sd_string_size_ptr); try { return(Marshal.PtrToStringAuto(sdString)); } finally { Marshal.FreeHGlobal(sdString); } } finally { FileSecurityNativeMethods.LocalFree(psd); } }
private static string GetDomainSid(string accountName) { uint sidLength = 0; uint domainNameLength = 0; byte[] sid = null; StringBuilder domainName = new StringBuilder(); FileSecurityNativeMethods.SID_NAME_USE peUse; // Query buffer size requirement by passing in NULL for Sid and ReferencedDomainName if (!FileSecurityNativeMethods.LookupAccountName(null, // lpSystemName accountName, null, // Sid ref sidLength, domainName, // ReferencedDomainName ref domainNameLength, out peUse)) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != FileSecurityNativeMethods.ERROR_INSUFFICIENT_BUFFER) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } sid = new byte[sidLength]; domainName.EnsureCapacity((int)domainNameLength); if (!FileSecurityNativeMethods.LookupAccountName(null, accountName, sid, ref sidLength, domainName, ref domainNameLength, out peUse)) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { throw new TransferException("Unexpected LookupAccountName success"); } // Get domain Sid from User Sid uint domainSidLength = 0; byte[] domainSid = null; if (!FileSecurityNativeMethods.GetWindowsAccountDomainSid(sid, domainSid, ref domainSidLength)) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != FileSecurityNativeMethods.ERROR_INSUFFICIENT_BUFFER) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } domainSid = new byte[domainSidLength]; if (!FileSecurityNativeMethods.GetWindowsAccountDomainSid(sid, domainSid, ref domainSidLength)) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { throw new TransferException("Unexpected GetWindowsAccountDomainSid success"); } // Get string corresponding to SID IntPtr domainSidPtr; if (!FileSecurityNativeMethods.ConvertSidToStringSid(domainSid, out domainSidPtr)) { throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); } try { return(Marshal.PtrToStringAuto(domainSidPtr)); } finally { FileSecurityNativeMethods.LocalFree(domainSidPtr); } }