Windows中有效的文件权限工具的api

从Windows Server 2003开始,Windows包含一个新工具,用于计算用户的有效权限(基本上它可以解析所有组访问权限并处理所有“拒绝”权限)。 一个例子是用户A属于组B和C.B已被拒绝对文件F的读取权限,而C已被允许对文件的读写权限,我想计算用户A具有的有效权限在档案F.
通过右键单击文件并转到属性 – >安全性 – >高级 – >有效权限,可以在Windows Server 2003,Vista,7和Server 2008上使用此工具。

我需要的是C#中的API,它可以完成同样的工作。 最常见的FILE API返回访问规则(类FileAccessRules),但似乎没有直接的方法来从这些访问规则集计算有效权限。
注意:如果可能的话,我不想在代码中处理有效的权限,但我已准备好作为最后的手段。

一些快速代码:

using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Security.AccessControl; namespace ConsoleApplication1 { class Program { [DllImport("advapi32.dll", SetLastError = true)] static extern uint GetEffectiveRightsFromAcl(IntPtr pDacl, ref TRUSTEE pTrustee, ref ACCESS_MASK pAccessRights); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] struct TRUSTEE { IntPtr pMultipleTrustee; // must be null public int MultipleTrusteeOperation; public TRUSTEE_FORM TrusteeForm; public TRUSTEE_TYPE TrusteeType; [MarshalAs(UnmanagedType.LPStr)] public string ptstrName; } enum TRUSTEE_FORM { TRUSTEE_IS_SID, TRUSTEE_IS_NAME, TRUSTEE_BAD_FORM, TRUSTEE_IS_OBJECTS_AND_SID, TRUSTEE_IS_OBJECTS_AND_NAME } enum TRUSTEE_TYPE { TRUSTEE_IS_UNKNOWN, TRUSTEE_IS_USER, TRUSTEE_IS_GROUP, TRUSTEE_IS_DOMAIN, TRUSTEE_IS_ALIAS, TRUSTEE_IS_WELL_KNOWN_GROUP, TRUSTEE_IS_DELETED, TRUSTEE_IS_INVALID, TRUSTEE_IS_COMPUTER } [DllImport("advapi32.dll", CharSet = CharSet.Auto)] static extern uint GetNamedSecurityInfo( string pObjectName, SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out IntPtr pSecurityDescriptor); enum ACCESS_MASK : uint { DELETE = 0x00010000, READ_CONTROL = 0x00020000, WRITE_DAC = 0x00040000, WRITE_OWNER = 0x00080000, SYNCHRONIZE = 0x00100000, STANDARD_RIGHTS_REQUIRED = 0x000f0000, STANDARD_RIGHTS_READ = 0x00020000, STANDARD_RIGHTS_WRITE = 0x00020000, STANDARD_RIGHTS_EXECUTE = 0x00020000, STANDARD_RIGHTS_ALL = 0x001f0000, SPECIFIC_RIGHTS_ALL = 0x0000ffff, ACCESS_SYSTEM_SECURITY = 0x01000000, MAXIMUM_ALLOWED = 0x02000000, GENERIC_READ = 0x80000000, GENERIC_WRITE = 0x40000000, GENERIC_EXECUTE = 0x20000000, GENERIC_ALL = 0x10000000, DESKTOP_READOBJECTS = 0x00000001, DESKTOP_CREATEWINDOW = 0x00000002, DESKTOP_CREATEMENU = 0x00000004, DESKTOP_HOOKCONTROL = 0x00000008, DESKTOP_JOURNALRECORD = 0x00000010, DESKTOP_JOURNALPLAYBACK = 0x00000020, DESKTOP_ENUMERATE = 0x00000040, DESKTOP_WRITEOBJECTS = 0x00000080, DESKTOP_SWITCHDESKTOP = 0x00000100, WINSTA_ENUMDESKTOPS = 0x00000001, WINSTA_READATTRIBUTES = 0x00000002, WINSTA_ACCESSCLIPBOARD = 0x00000004, WINSTA_CREATEDESKTOP = 0x00000008, WINSTA_WRITEATTRIBUTES = 0x00000010, WINSTA_ACCESSGLOBALATOMS = 0x00000020, WINSTA_EXITWINDOWS = 0x00000040, WINSTA_ENUMERATE = 0x00000100, WINSTA_READSCREEN = 0x00000200, WINSTA_ALL_ACCESS = 0x0000037f } [Flags] enum SECURITY_INFORMATION : uint { OWNER_SECURITY_INFORMATION = 0x00000001, GROUP_SECURITY_INFORMATION = 0x00000002, DACL_SECURITY_INFORMATION = 0x00000004, SACL_SECURITY_INFORMATION = 0x00000008, UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000, UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000, PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000, PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000 } enum SE_OBJECT_TYPE { SE_UNKNOWN_OBJECT_TYPE = 0, SE_FILE_OBJECT, SE_SERVICE, SE_PRINTER, SE_REGISTRY_KEY, SE_LMSHARE, SE_KERNEL_OBJECT, SE_WINDOW_OBJECT, SE_DS_OBJECT, SE_DS_OBJECT_ALL, SE_PROVIDER_DEFINED_OBJECT, SE_WMIGUID_OBJECT, SE_REGISTRY_WOW64_32KEY } static void Main(string[] args) { String user = "DOMAIN\\USER"; String Path = "C:\\"; IntPtr pSidOwner, pSidGroup, pDacl, pSacl, pSecurityDescriptor; ACCESS_MASK mask = new ACCESS_MASK(); uint ret = GetNamedSecurityInfo(Path, SE_OBJECT_TYPE.SE_FILE_OBJECT, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, out pSidOwner, out pSidGroup, out pDacl, out pSacl, out pSecurityDescriptor); TRUSTEE t = new TRUSTEE(); t.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME; t.TrusteeType= TRUSTEE_TYPE.TRUSTEE_IS_USER; t.ptstrName = user; ret = GetEffectiveRightsFromAcl(pDacl, ref t , ref mask); if ((mask & ACCESS_MASK.READ_CONTROL) == ACCESS_MASK.READ_CONTROL) { System.Diagnostics.Debug.WriteLine("Read"); } else { System.Diagnostics.Debug.WriteLine("No Read"); } } } } 

我在advapi32.dll中找到了一个名为GetEffectiveRightsFromAcl的函数。 这似乎正是我想要的。 实际上,有效权限工具使用AuthzAccessCheckfunction。 我使用它,并没有像我想象的那样发现性能下降。 (但是,我被告知Authz不包含Windows 7及更高版本中提供的“完整性”概念,并且可能会报告错误的结果。)

您可以使用Windows提供的Authz API确定用户对文件/文件夹的有效权限。 请点击以下链接。 https://msdn.microsoft.com/en-us/library/windows/desktop/ff394768(v=vs.85).aspx也是这个。 https://msdn.microsoft.com/en-us/library/windows/desktop/aa446637(v=vs.85).aspx 。 我已经在从Windows Server 2003开始的所有Windows版本中尝试了这一点,并且获得了相当不错的性能。