我使用Java7中的AclFileAttributeView来读取Windows目录的文件夹权限。 问题是,我无法得到一个完整的概述,因为AclFileAttributeView不会返回像GENERIC_ALL,GENERIC_WRITE,GENERIC_READ和GENERIC_EXECUTE(访问掩码中的四个高阶位)的一般权限。 实际上,当涉及到通用权限时,它给了我关于同一成员的其他AclEntries的错误信息。 让我举个例子:

当我使用像AccessChk这样的工具来列出系统帐户的c:\ windows的AclEntries时,我得到以下内容:

[2] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM FILE_ADD_FILE FILE_ADD_SUBDIRECTORY FILE_LIST_DIRECTORY FILE_READ_ATTRIBUTES FILE_READ_EA FILE_TRAVERSE FILE_WRITE_ATTRIBUTES FILE_WRITE_EA DELETE SYNCHRONIZE READ_CONTROL [3] ACCESS_ALLOWED_ACE_TYPE: NT AUTHORITY\SYSTEM [OBJECT_INHERIT_ACE] [CONTAINER_INHERIT_ACE] [INHERIT_ONLY_ACE] GENERIC_ALL

正如你所看到的,第一个AclEntry只适用于文件夹本身,并没有特殊的权限WRITE_ACL和WRITE_OWNER。 第二个AclEntry仅适用于子文件夹和文件,并且包含通用权限GENERIC_ALL。 这正是我在Windows资源pipe理器的“安全”选项卡中看到的。 系统帐户的两个logging,一个仅适用于文件夹(具有权限子集),一个适用于具有完全控制的子文件夹/文件。

现在我使用下面的代码运行我的java程序:AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class); System.out.println(view.getAcl());

这给了我系统帐户的以下结果:

NT AUTHORITY \ SYSTEM:READ_DATA / WRITE_DATA / APPEND_DATA / READ_NAMED_ATTRS / WRITE_NAMED_ATTRS / EXECUTE / DELETE_CHILD / READ_ATTRIBUTES / WRITE_ATTRIBUTES / DELETE / READ_ACL / WRITE_ACL / WRITE_OWNER / SYNCHRONIZE:ALLOW

NT AUTHORITY \ SYSTEM:FILE_INHERIT / DIRECTORY_INHERIT / INHERIT_ONLY:ALLOW

第一个AclEntry只适用于文件夹本身,并包含所有的特殊权限,包括WRITE_ACL和WRITE_OWNER,这是不正确的! 第二个AclEntry不显示任何权限,因为它上面有GENERIC_ALL!

我不确定这是哪里出错,看来JRE只是解码操作系统给出的ACE位掩码(sun.nio.fs.WindowsSecurityDescriptor.decode)。

有没有人遇到这些相同的问题? 我会尝试一些其他的JRE,也许这是有所作为的。

我也遇到了同样的问题。 事实证明,AclFileAttributeView的规范声明它被设计为与RFC 3530:网络文件系统(NFS)版本4协议兼容。 在RFC 3530中,不支持GENERIC_ *值。 我还查看了运行JVM的JDK代码源(从这里下载的OpenJDK项目 )。 虽然在我看来,有一种方法可以通过从GENERIC_ *映射合适的RFC 3530标记来使JVM兼容,维护者显然没有。 这是您的空输入NT AUTHORITY \ SYSTEM:FILE_INHERIT / DIRECTORY_INHERIT / INHERIT_ONLY:ALLOW的原因

更糟糕的是,JVM不支持Windows安全描述符(通过元标志(UN)PROTECTED_(S / D)ACL_SECURITY_INFORMATION设置的SE_DACL_PROTECTED和SE_SACL_PROTECTED标志,如注释中所示,如果使用工具AccessChk ,显示你有效的ACE列表,而不是AclFileAttributeView和其他Windows工具所做的实际 ACE列表(查看FileTest) 。这就是ACE数量不同的原因。在我的例子中,我有9个ACE,但AccessChk显示5。其中4个是真正重复的SID(用户或组)的值,其中给定SID的第一个ACE具有权限,给定SID的第二个ACE没有权限,但是只有SE_DACL_PROTECTED设置或未设置。

我不完全确定你想用这些ACL来做什么,但是根据你的意图,我可能会有一个解决方案。 我继续前进,对JNA项目进行了更改,开始允许更直接地修改Windows安全描述符。 你可以在这里看到我的合并请求。 我不知道他们多久发布一个版本到Maven public repo,所以你可能需要直接下载和编译源代码来获得这些改变。 有关如何获取对象的SD,请参阅GetNamedSecurityInfo。 然后,您可以使用AdvApi32Util中的帮助API来处理SECURITY_DESCRIPTOR对象。 请参阅public static SECURITY_DESCRIPTOR_RELATIVE getFileSecurityDescriptor(File file, boolean getSACL)的一种方式来获取SD自相对格式,然后该对象允许您走过ACL中的ACE。

我最终使用反射来获取ACE的访问掩码(使用sun.nio.fs.WindowsNativeDispatcher.GetAce)。 通过访问掩码,我检查四个高位来确定通用权限。

它也允许我得到INHERITED_ACE位,这在JRE规范中是不可用的。 我得到了'原始的'ACL信息,这是比Windows安全选项卡更多。 例如,我的c:\驱动器为我提供了两个用于BUILT-IN \ Administrators的ACE,一个具有GENERIC_ALL权限并传播到子文件夹和文件(而不是容器本身),另一个具有应用的特殊权限,仅适用于当前容器)。 这就是Windows使用这些通用权限的方式。 这同样适用于子文件夹,如Program Files目录,泛型权限将被传播,并且每个子容器都有一个单独的ACE,仅用于实际的仅适用于容器本身的特殊权限。

关于AccessChck工具,你确定使用了-l参数吗? 这给了更多的信息和“原始的”ACL信息。

我已经使用JNA Project从服务器检索本地组。 感谢关于AdvApi32Util的提示! 我会仔细看看的。 您在JRE中使用setACL方法的经验如何?

我使用所有这些来发布一个工具,该工具将来自LDAP的组成员身份与目录和文件中的ACL信息结合起来。 所有这些信息保存在本地数据库(或外部)中,可用于创建概览。 此概述提供了许多过滤器选项,并显示特定用户或一组用户的权限信息(包括嵌套组成员资格)。 因为所有内容都保存在数据库中,所以每秒都可以在几秒钟内完成概览,而不是每次扫描整个网络。 您还可以跟踪权限,显示权限来自何处,组成员身份或文件夹等。它将包含修改单个ACE的功能,但重点在于查看权限。

该工具已准备好进行测试;)让我知道你是否感兴趣…该工具不会免费,因为它花了我很多时间写,但让我知道,如果你有兴趣。 我可以拿到你的执照。 请参阅以下链接以获得快速印象。 不介意这个网站,它仍然提到了一个老版本的工具。

扫描截图

概述截图

权限分析器64位

权限分析器32bit

权限分析器64位嵌入式JRE

权限分析器32位嵌入式JRE