Reputation: 13130
In my application that allows users to modify their music files occasionally I have a problem when application does not have permissions to modify a file but the user is convinced they have given it full permissions
I've discovered the Java 7 improvements and wrote this method to output the permissions
public static String displayPermissions(Path path)
{
StringBuilder sb = new StringBuilder();
sb.append("File "+path + " permissions\n");
try
{
{
AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
if (view != null)
{
for (AclEntry acl : view.getAcl())
{
sb.append(acl+"\n");
}
}
}
{
PosixFileAttributeView view = Files.getFileAttributeView(path, PosixFileAttributeView.class);
if (view != null)
{
PosixFileAttributes pfa = view.readAttributes();
sb.append(":owner:"+pfa.owner().getName()+":group:"+pfa.group().getName()+":"+PosixFilePermissions.toString(pfa.permissions())+"\n");
}
}
}
catch(IOException ioe)
{
logger.severe("Unable to read permissions for:"+path.toString());
}
return sb.toString();
}
but for Windows systems it can still be rather difficult/impossible to work out why they don't have permissions
WARNING: File testdata\test157.dsf permissions
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:DENY
BUILTIN\Administrators: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:DENY
BUILTIN\Administrators: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: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
BUILTIN\Users:READ_DATA/READ_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/READ_ACL/SYNCHRONIZE:ALLOW
NT AUTHORITY\Authenticated Users:READ_DATA/WRITE_DATA/APPEND_DATA/READ_NAMED_ATTRS/WRITE_NAMED_ATTRS/EXECUTE/READ_ATTRIBUTES/WRITE_ATTRIBUTES/DELETE/READ_ACL/SYNCHRONIZE:ALLOW
, any suggestions on how I can programmatically work out the reason for isWritable() (or isReadable()) failing.
Upvotes: 3
Views: 2623
Reputation: 22983
I believe the confusion comes from the fact that the effective permission depends on the directory permissions and the file permissions.
If the user has e.g. the Write
permission for a file but not the Modify
permission for the containing directory he has effectively not write permission to that file. See the full matix of File and folder permissions.
To do the check in Java you can use the FileSystemProvider.checkAccess method to check the permission of
Assume following files and permissions (all permissions out of scope are removed to make it more clear). The permissions were retrieved with the icacls
tool.
c:\ BUILTIN\Users:(OI)(CI)(RX) - read + execute permission
c:\bar BUILTIN\Users:(RX) - read + execute permission
c:\foo BUILTIN\Users:(F) - full permission
Sample snippet for demonstration.
public class AccessCheckDemo {
public static void main(String[] args) throws IOException {
String[] files = {"c:/foo", "c:/bar"};
for (String file : files) {
Path path = Paths.get(file);
System.out.println("check " + path);
System.out.println("file Files.isWritable: "
+ Files.isWritable(path));
System.out.println("directory Files.isWritable: "
+ Files.isWritable(path.getParent()));
System.out.println();
}
}
}
output
check c:\foo
file Files.isWritable: true
directory Files.isWritable: false
check c:\bar
file Files.isWritable: true
directory Files.isWritable: false
Even BUILTIN\Users
have full permissions
on file c:\foo
they cannot write to this file, as the permission of the directory c:\
does not permit it (only read + execute permission for this group on c:\
).
As already mentioned by badsamaritan (JDK-7190897) this doesn't work properly in Java 7.
Upvotes: 3
Reputation: 447
any suggestions on how I can programmatically work out the reason for isWritable() (or isReadable()) failing
Maybe it is real bug, not your fault:
https://bugs.openjdk.java.net/browse/JDK-8034863
or
http://bugs.java.com/view_bug.do?bug_id=7190897
When talking about Windows permissions it is worth mentioning that they are indeed a bit strange (even Microsoft admits it): DENY has stronger priority than ALLOW, so if you allow some users to read particular file and also deny everyone every permission this deny 'overrides' everything and no one (including owner) can't read this file. That's why you don't see DENY permission selected in ACLs very often.
Upvotes: 1