1

I'm trying to write code that starts with a Path object that is for a specific file and makes it so the owner of the file no longer has permissions to move it, delete it, or modify it, but they can still read it. Also need to make sure that this can be undone, as well as maintain unrestricted access for administrators at all times.

One of my main problems is that I can't figure out how to get the user profile names and group names that are in the system.

An in-depth explanation would be fantastic.

JereTheJuggler
  • 127
  • 1
  • 2
  • 9
  • I actually figured out how to get the result I wanted more or less. The only thing I still am unsure of is if it is actually possible to remove a user's permission to move a file, and if it is possible then how. – JereTheJuggler Jun 12 '16 at 02:05
  • Its quite complicated, let me show you how in an answer. At least I think this works, I am the only user and an administrator so I can't test it – JD9999 Jun 12 '16 at 02:10

1 Answers1

-2

The File class can set a file for reading, writing, and executing. To get it by user, you need to use NIO.

The Files class and NIO uses PosixFilePermissions, which sets permissions by file and by three groups: User, owner, and Group. On Windows, Administrators will be in a group, as well as System.

To move it we need our own SecurityManager. When moving files, NIO uses the write permission. So our SecurityManager has to modify the write permission. See my code below as an example.

p.s. although the FileSystemsProvider is WindowsFileSystemProvider, this is returned by FileSystemProviders.getProvider (or the method similar). Its possible that the rt.jar is different for each OS downloaded on, but if you're on Windows you can assume this is correct.

PathRestrictor.java

package Testers;

import java.io.IOException;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import sun.nio.fs.WindowsFileSystemProvider;


public class PathRestrictor extends FileSystemProvider{

    boolean canRead;
    boolean canWrite;
    boolean canMove; //This is the tricky one
    boolean canOpen;
    private Path path;
    WindowsFileSystemProvider provider = new WindowsFileSystemProvider();

    public PathRestrictor(Path p){
        path = p;
        canRead = true;
        canWrite = true;
        canOpen = true;
    }

    public void setExecuteable(boolean executable){
        canOpen = executable;
        try {
            Files.setPosixFilePermissions(path, getPerms());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setReadable(boolean readable){
        canRead = readable;
        try {
            Files.setPosixFilePermissions(path, getPerms());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setWriteable(boolean writeable){
        canWrite = writeable;
        try {
            Files.setPosixFilePermissions(path, getPerms());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setMoveable(boolean moveable){
        canMove = moveable;
        MovementSecurityManager manager = new MovementSecurityManager();
        if(!moveable)manager.unMoveablePaths.add(path.toString());
        else manager.unMoveablePaths.remove(path.toString());
        System.setSecurityManager(manager);


    }

    private Set<PosixFilePermission> getPerms() {
        Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
        perms.add(PosixFilePermission.GROUP_EXECUTE);
        perms.add(PosixFilePermission.GROUP_READ);
        perms.add(PosixFilePermission.GROUP_WRITE);
        if(canRead){
            perms.add(PosixFilePermission.OTHERS_READ);
            perms.add(PosixFilePermission.OWNER_READ);
        }
        if(canWrite){
            perms.add(PosixFilePermission.OTHERS_WRITE);
            perms.add(PosixFilePermission.OWNER_WRITE);
        }
        if(canOpen){
            perms.add(PosixFilePermission.OTHERS_EXECUTE);
            perms.add(PosixFilePermission.OWNER_EXECUTE);
        }
        return perms;
    }

    @Override
    public void checkAccess(Path path, AccessMode... modes) throws IOException {
        provider.checkAccess(path, modes);
    }

    @Override
    public void copy(Path source, Path target, CopyOption... options)
            throws IOException {
        // TODO Auto-generated method stub
        provider.copy(source, target, options);

    }

    @Override
    public void createDirectory(Path dir, FileAttribute<?>... attrs)
            throws IOException {
        provider.createDirectory(dir, attrs);
    }

    @Override
    public void delete(Path path) throws IOException {
        provider.delete(path);
    }

    @Override
    public <V extends FileAttributeView> V getFileAttributeView(Path path,
            java.lang.Class<V> type, LinkOption... options) {
        return provider.getFileAttributeView(path, type, options);
    }

    @Override
    public FileStore getFileStore(Path path) throws IOException {
        return provider.getFileStore(path);
    }

    @Override
    public FileSystem getFileSystem(URI uri) {
        return provider.getFileSystem(uri);
    }

    @Override
    public Path getPath(URI uri) {
        return provider.getPath(uri);
    }

    @Override
    public String getScheme() {
        return provider.getScheme();
    }

    @Override
    public boolean isHidden(Path path) throws IOException {
        return provider.isHidden(path);
    }

    @Override
    public boolean isSameFile(Path path, Path path2) throws IOException {
        return path.toString().equals(path2.toString());
    }

    @Override
    public void move(Path source, Path target, CopyOption... options)
            throws IOException {
            MovementSecurityManager manager = new MovementSecurityManager();
            manager.isMoving = true;
            System.setSecurityManager(manager);
            provider.move(source, target, options);
    }

    @Override
    public SeekableByteChannel newByteChannel(Path path,
            Set<? extends OpenOption> options, FileAttribute<?>... attrs)
            throws IOException {
        return provider.newByteChannel(path, options, attrs);
    }

    @Override
    public DirectoryStream<Path> newDirectoryStream(Path dir,
            Filter<? super Path> filter) throws IOException {
        return provider.newDirectoryStream(dir, filter);
    }

    @Override
    public FileSystem newFileSystem(URI uri, Map<String, ?> env)
            throws IOException {
        return provider.newFileSystem(uri, env);
    }

    @Override
    public <A extends BasicFileAttributes> A readAttributes(Path path,
            java.lang.Class<A> type, LinkOption... options) throws IOException {
        return provider.readAttributes(path, type, options);
    }

    @Override
    public Map<String, Object> readAttributes(Path path, String attributes,
            LinkOption... options) throws IOException {
        return provider.readAttributes(path, attributes, options);
    }

    @Override
    public void setAttribute(Path path, String attribute, Object value,
            LinkOption... options) throws IOException {
        provider.setAttribute(path, attribute, value, options);

    }

}

MovementSecurityManager.java

package Testers;

import java.util.HashSet;
import java.util.Set;

public class MovementSecurityManager extends SecurityManager {

    public Set<String> unMoveablePaths = new HashSet<String>();
    public boolean isMoving = true;

    public void checkWrite(String path){
        if(unMoveablePaths.contains(path) && isMoving) throw new SecurityException("Cannot move file!");
        else super.checkWrite(path);
    }

}
JD9999
  • 394
  • 1
  • 7
  • 18