【问题标题】:Setting ACL with java fails on subfolder (missing inheritance)在子文件夹上使用 java 设置 ACL 失败(缺少继承)
【发布时间】:2014-02-26 18:20:58
【问题描述】:

以下代码为组 G-Test 设置文件夹“\\myShare\Folder1\”的“读取”权限:

String gName="G-Test";
AclEntryPermission[] aeps=new AclEntryPermission[]{
        AclEntryPermission.READ_DATA,
        AclEntryPermission.READ_ATTRIBUTES,
        AclEntryPermission.READ_NAMED_ATTRS,
        AclEntryPermission.READ_ACL,
        AclEntryPermission.SYNCHRONIZE
    };      
Path p = FileSystems.getDefault().getPath(new File("\\\\myShare\\Folder1\\").getPath());
AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
for (AclEntryPermission acp: aeps) set.add(acp);
AclEntry.Builder b= AclEntry.newBuilder();
b.setType(AclEntryType.ALLOW);
b.setPermissions(set);
b.setPrincipal(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName(gName));
b.setFlags(new AclEntryFlag[]{AclEntryFlag.FILE_INHERIT,AclEntryFlag.DIRECTORY_INHERIT});       
List<AclEntry> acl = view.getAcl();
acl.add(b.build());
view.setAcl(acl);

这适用于文件夹 1,如预期的那样。但是在 Folder2(子文件夹:\\myShare\Folder1\Folder2)上,ACL 没有被继承。使用 Windows GUI 查看时,Folder2 中缺少继承的 ACL。

在使用 Windows 为 Folder1 中的另一个组/权限更改 ACL 时,我可以看到以前在 folder2 上缺少的权限。或者在创建新的子文件夹时,ACL 是正确继承的。

上面的代码有问题吗?我想在 folder1 上设置读取权限,该权限被继承到所有子文件夹和文件。

代码在 Windows 8.1 PC 上运行,共享是 Windows 2008 R2 文件 - 集群

【问题讨论】:

    标签: java file-permissions


    【解决方案1】:

    您的代码运行良好。我有一个几乎相同的结构来在我的环境中设置权限,它也可以在那里工作。问题是修改权限时Folder2已经存在。一些 Windows API 调用将更改沿目录树传播,而另一些则不会(请参阅this question 的答案)。 JRE 必须使用不使用的其中之一。我猜你必须自己走树来传播变化。但是,如果您在设置权限后创建 Folder2,那么它将具有从顶部继承的权限(至少在我的上是这样)。

    编辑: 我对这个问题进行了更多思考,并认为我将来可能也需要走那棵树。因为我们在这里讨论的是 Java 7,所以我寻找了一种比以前更容易走树的方法。事实证明,Files.walkFileTree() 方法只是票!我想出了这个,虽然我会分享它:

    private void grantAccess(final UserPrincipal user, Path folder) {
        try {
            Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {              
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    grant(dir);
                    return FileVisitResult.CONTINUE;
                }
    
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    grant(file);
                    return FileVisitResult.CONTINUE;
                }
    
                private void grant(Path p) throws IOException {
                    AclFileAttributeView view = Files.getFileAttributeView(p, AclFileAttributeView.class);
                    AclEntry accessEntry = createAccessACLEntry(user);
                    List<AclEntry> acl = view.getAcl();
                    acl.add(0, accessEntry); // insert at head in case there are any DENY entries
                    view.setAcl(acl);
                }
    
                private AclEntry createAccessACLEntry(UserPrincipal user) {
                    AclEntry entry = AclEntry
                            .newBuilder()
                            .setType(AclEntryType.ALLOW)
                            .setPrincipal(user)
                            .setPermissions(AclEntryPermission.DELETE_CHILD,
                                    AclEntryPermission.WRITE_NAMED_ATTRS,
                                    AclEntryPermission.EXECUTE,
                                    AclEntryPermission.WRITE_DATA,
                                    AclEntryPermission.WRITE_ATTRIBUTES,
                                    AclEntryPermission.READ_ATTRIBUTES,
                                    AclEntryPermission.APPEND_DATA,
                                    AclEntryPermission.READ_DATA,
                                    AclEntryPermission.READ_NAMED_ATTRS,
                                    AclEntryPermission.READ_ACL,
                                    AclEntryPermission.SYNCHRONIZE,
                                    AclEntryPermission.DELETE)
                            .setFlags(AclEntryFlag.FILE_INHERIT,
                                    AclEntryFlag.DIRECTORY_INHERIT)   
                            .build();
                    return entry;
                }
            });
        } catch (IOException e) {
            throw new IllegalStateException("Unable to grant access for " + folder.toString() + " to " + user.getName(), e);
        }
    }
    

    您必须同时覆盖 visitFile() 和 preVisitDirectory(),以便更改文件和文件夹的权限,尽管您可以用 postVisitDirectory() 替换 preVisitDirectory()。

    【讨论】:

      猜你喜欢
      • 2017-05-31
      • 1970-01-01
      • 2016-01-11
      • 2022-11-05
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2011-03-17
      相关资源
      最近更新 更多