windows下有效文件权限工具的api

Posted

技术标签:

【中文标题】windows下有效文件权限工具的api【英文标题】:Effective file permissions tool's api in windows 【发布时间】:2011-03-02 14:11:08 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

您可以使用 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 版本中进行了尝试,并获得了相当不错的性能。

【讨论】:

【参考方案2】:

一些快速代码:

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");
            

        
    

【讨论】:

这在我的系统上冻结(Win 7 和 XP)。有什么想法吗? 只要用户有权查看文件或文件夹,这对我有用。如果用户拒绝查看文件夹或文件的查看权限和读取权限,则不会返回掩码,这会错误地返回“读取”(我让它返回“真”)。 “酷”的事情是我可以用它绕过查看权限并查看通常对我隐藏的文件夹。【参考方案3】:

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

【讨论】:

以上是关于windows下有效文件权限工具的api的主要内容,如果未能解决你的问题,请参考以下文章

Windows文件管理器登录Ftp服务提示请检查是不是有权限

Win API函数修改文件权限

LINUX修改文件权限

Windows文件服务器共享的时候分配权限对于目录深文件量大的情况下,权限写入非常慢,有啥办法可以解决

windows7 共享文件夹 访问权限

在管理员权限下删除管理员无删除权限的文件夹(windows)