Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - unable to create directory with 777 permission (has 775 instead) [duplicate]

I'm trying to create directory with public write permissions. To simplify things I want it to have 777 permissions. Here's my code:

private static FileAttribute<Set<PosixFilePermission>> DIR_PERMISSIONS;
static {
    Set<PosixFilePermission> perms = new HashSet<>();
    perms.add(PosixFilePermission.OWNER_WRITE);
    perms.add(PosixFilePermission.OWNER_READ);
    perms.add(PosixFilePermission.OWNER_EXECUTE);
    perms.add(PosixFilePermission.GROUP_WRITE);
    perms.add(PosixFilePermission.GROUP_READ);
    perms.add(PosixFilePermission.GROUP_EXECUTE);
    perms.add(PosixFilePermission.OTHERS_WRITE);
    perms.add(PosixFilePermission.OTHERS_READ);
    perms.add(PosixFilePermission.OTHERS_EXECUTE);
    DIR_PERMISSIONS = PosixFilePermissions.asFileAttribute(perms);
}

private Path ensurePath(LocalDate localDate) throws IOException {
    String year = String.valueOf(localDate.getYear());
    String month = String.format("%02d", localDate.getMonthValue());
    Path path = Paths.get(rootDirectory, year, month);
    return Files.createDirectories(path, DIR_PERMISSIONS);
}

With rootDirectory=/tmp/data this should create folders like /tmp/data/2016/01, each with 777 permissions. Instead folders have 775 permissions (drwxrwxr-x.) so they are lacking public write. Why is it working this way? Maybe JVM needs special param to be able to set such permissions? My system is Fedora 24, app is standard Spring Boot application, started by maven plugin.

like image 894
xianoss Avatar asked Jan 26 '17 15:01

xianoss


1 Answers

Okay well this got me curious so here goes:

Google led to this: https://stackoverflow.com/a/25557947/6768037 ("Java is setting the permission you seek and then it's being masked out.") which then leads back to the link that @OlivierGrégoire originally provided. umask is a harsh mistress.

Spring Boot has nothing to do with this behavior. Below is a simple proof of concept. My default umask is 0002. My /tmp directory is initially empty.

public class Test {
    public static void main(String[] args) {
        Set<PosixFilePermission> fullPermission = new HashSet<PosixFilePermission>();
        fullPermission.add(PosixFilePermission.OWNER_EXECUTE);
        fullPermission.add(PosixFilePermission.OWNER_READ);
        fullPermission.add(PosixFilePermission.OWNER_WRITE);

        fullPermission.add(PosixFilePermission.GROUP_EXECUTE);
        fullPermission.add(PosixFilePermission.GROUP_READ);
        fullPermission.add(PosixFilePermission.GROUP_WRITE);

        fullPermission.add(PosixFilePermission.OTHERS_EXECUTE);
        fullPermission.add(PosixFilePermission.OTHERS_READ);
        fullPermission.add(PosixFilePermission.OTHERS_WRITE);

        Path path = Paths.get("/tmp/data/", "01/26");
        try {
            Files.createDirectories(path, PosixFilePermissions.asFileAttribute(fullPermission));            
            outputLS(path);         
            Files.setPosixFilePermissions(path, fullPermission);            
            outputLS(path);         
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void outputLS(Path path) throws IOException {
        System.out.println(new java.util.Scanner(Runtime.getRuntime().exec("ls -alt " + path.toAbsolutePath() + "/..").getInputStream()).useDelimiter("\\A").next());
    }
}

Yields:

total 12
drwxrwxr-x 3 jsampson jsampson 4096 Jan 26 21:53 .
drwxrwxr-x 2 jsampson jsampson 4096 Jan 26 21:53 26
drwxrwxr-x 3 jsampson jsampson 4096 Jan 26 21:53 ..

total 12
drwxrwxr-x 3 jsampson jsampson 4096 Jan 26 21:53 .
drwxrwxrwx 2 jsampson jsampson 4096 Jan 26 21:53 26
drwxrwxr-x 3 jsampson jsampson 4096 Jan 26 21:53 ..

umask simply is in charge of all file/directory creation permissions. After creation it's possible to make changes.

like image 141
Jon Sampson Avatar answered Sep 22 '22 04:09

Jon Sampson