@Override public void setAcl(List<AclEntry> acl) throws IOException { // permission check checkAccess(file, false, true); // open file (will fail if file is a link and not following links) int fd = file.openForAttributeAccess(followLinks); try { // SECURITY: need to copy list as can change during processing acl = new ArrayList<AclEntry>(acl); int n = acl.size(); long address = unsafe.allocateMemory(SIZEOF_ACE_T * n); try { encode(acl, address); facl(fd, ACE_SETACL, n, address); } catch (UnixException x) { if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) { throw new FileSystemException( file.getPathForExceptionMessage(), null, x.getMessage() + " (file system does not support NFSv4 ACLs)"); } if (x.errno() == EINVAL && (n < 3)) throw new IOException("ACL must contain at least 3 entries"); x.rethrowAsIOException(file); } finally { unsafe.freeMemory(address); } } finally { close(fd); } }
@Override public List<AclEntry> getAcl() throws IOException { // permission check checkAccess(file, true, false); // open file (will fail if file is a link and not following links) int fd = file.openForAttributeAccess(followLinks); try { long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES); try { // read ACL and decode it int n = facl(fd, ACE_GETACL, MAX_ACL_ENTRIES, address); assert n >= 0; return decode(address, n); } catch (UnixException x) { if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) { throw new FileSystemException( file.getPathForExceptionMessage(), null, x.getMessage() + " (file system does not support NFSv4 ACLs)"); } x.rethrowAsIOException(file); return null; // keep compiler happy } finally { unsafe.freeMemory(address); } } finally { close(fd); } }
/** Permission checks to access file */ private void checkAccess(UnixPath file, boolean checkRead, boolean checkWrite) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { if (checkRead) file.checkRead(); if (checkWrite) file.checkWrite(); sm.checkPermission(new RuntimePermission("accessUserInformation")); } }