0

The following Code sets "Read" Permissions on the folder "\\myShare\Folder1\" for the Group G-Test:

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

This works for folder1 as expected. But on Folder2 (subfolder: \\myShare\Folder1\Folder2) the ACL is not inherited. When looking with the Windows GUI the inherited ACL is missing in Folder2.

When changing the ACL with Windows for another Group/Permission in Folder1, i could see the previous missing permission on folder2. Or on creating an new Subfolder the ACL is correct inherited.

Is something wrong with the code above? I want to set Read-Permissions on folder1 wich were inherited to all subfolders and files.

The code runs on a Windows 8.1 PC and the share is a Windows 2008 R2 File - Cluster

pnuts
  • 58,317
  • 11
  • 87
  • 139
silence_le
  • 5
  • 1
  • 4

1 Answers1

3

Your code works fine. I have an almost identical structure to set permissions in my environment and it works there also. The problem is that Folder2 already exist when the permissions are modified. Some of the Windows API calls propagate the changes down the directory tree and some do not (see the answer to this question). The JRE must be using one of the ones that does not. You'll have to walk the tree to propagate the changes yourself, I guess. However, if you create Folder2 after the permissions are set then it will have the permissions inherited from the top (at least it does on mine).

Edit: I thought about the problem some more and figured that I might need to walk the tree in the future also. Since we're talking Java 7 here I looked for an easier method for walking a tree than I'm used to. It turns out that the Files.walkFileTree() method is just the ticket! I came up with this and though I would share it:

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

You have to override both visitFile() and preVisitDirectory() so that you change permissions for both files and folders, though you could substitute postVisitDirectory() for preVisitDirectory().

Community
  • 1
  • 1
Jose Ferrer
  • 1,188
  • 1
  • 7
  • 9