How do you set the Windows ACL using Java 7's File API so that it mimics adding the user/group and the following options:
For example, in the OS Properties dialog, you can select the following for basic write access:
However, when I use similar options using Java 7's File API, it instead selects:
Not only is this harder to administer (traversing dialogs is easier to miss something), it doesn't behave the same was as simply clicking those boxes. Some of the UAC prompts behave differently. Worse, it's harder to toggle the permissions (e.g. from the Windows desktop) due to the dialog traversing, leaving more chance of making a mistake.
How do I use Java to set these checkboxes?
UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("Authenticated Users");
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
// Create ACL to give "Authenticated Users" "modify" access
AclEntry entry = AclEntry.newBuilder()
.setType(AclEntryType.ALLOW)
.setPrincipal(authenticatedUsers)
.setPermissions(DELETE, DELETE_CHILD, LIST_DIRECTORY, READ_DATA, READ_ATTRIBUTES, ADD_FILE, WRITE_DATA, WRITE_ATTRIBUTES)
.build();
List<AclEntry> acl = view.getAcl();
acl.add(0, entry); // insert before any DENY entries
view.setAcl(acl);
I was able to mimic the Windows Properties file permissions by making a folder that I wanted to mimic, setting the values through the Properties dialog, then echoing them back out...
// Echo ACL
Path path = Paths.get("C:\\myfolder");
UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("Authenticated Users");
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
for(AclEntry entry : view.getAcl()) {
if(entry.principal().equals(authenticatedUsers)) {
System.out.println("=== flags ===");
for (AclEntryFlag flags : entry.flags()) {
System.out.println(flags.name());
}
System.out.println("=== permissions ===");
for (AclEntryPermission permission : entry.permissions()) {
System.out.println(permission.name());
}
}
}
The output:
=== flags ===
DIRECTORY_INHERIT
FILE_INHERIT
=== permissions ===
WRITE_NAMED_ATTRS
WRITE_ATTRIBUTES
DELETE
WRITE_DATA
READ_ACL
APPEND_DATA
READ_ATTRIBUTES
READ_DATA
EXECUTE
SYNCHRONIZE
READ_NAMED_ATTRS
Then, I was able to plug these values back into my original example:
UserPrincipal authenticatedUsers = path.getFileSystem().getUserPrincipalLookupService()
.lookupPrincipalByName("Authenticated Users");
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
// Create ACL to give "Authenticated Users" "modify" access
AclEntry entry = AclEntry.newBuilder()
.setType(AclEntryType.ALLOW)
.setPrincipal(authenticatedUsers)
.setFlags(DIRECTORY_INHERIT,
FILE_INHERIT)
.setPermissions(WRITE_NAMED_ATTRS,
WRITE_ATTRIBUTES,
DELETE,
WRITE_DATA,
READ_ACL,
APPEND_DATA,
READ_ATTRIBUTES,
READ_DATA,
EXECUTE,
SYNCHRONIZE,
READ_NAMED_ATTRS)
.build();
... and now "Modify" is checked exactly as desired.