Can I override my umask using ACLs to make all files created in a given directory world readable?

Assume that my umask is 0077.

I have a directory, foo, that I want to have special permissions applied to it. All files I create in foo should be world readable, and all directories should be world readable and executable.

Currently, if I create a file, it will be 0600, and a directory will be 0700:

$ cd foo/
$ touch file
$ mkdir directory
$ ls -l
drwx------ 2 nfm nfm 4096 2012-01-12 16:16 directory
-rw------- 1 nfm nfm    0 2012-01-12 16:15 file

I want the file to be 0644, and the directory 0755, regardless of my umask:

drwxr-xr-x 2 nfm nfm 4096 2012-01-12 16:16 directory
-rw-r--r-- 1 nfm nfm    0 2012-01-12 16:15 file

How can I achieve this?


Yes, ACLs can do this.

  1. Ensure your filesystem is mounted with acl. To check this, type mount. You should see acl listed among other permissions, e.g.

    /dev/sda1 on / type ext4 (rw,errors=remount-ro,acl)
    

    If it's not mounted with acl, open up /etc/fstab, and add acl to the list of options:

    # /etc/fstab: static file system information.
    #
    # <file system> <mount point>   <type>   <options>       <dump>  <pass>
    /dev/sda1       /          ext3     noatime,errors=remount-ro,acl 0       1
    

    Now, re-mount the running filesystem with the new options:

    mount -v -o remount /
    
  2. Install the acl utilities. On ubuntu/debian, this is:

    sudo apt-get install acl
    
  3. Your new friends are setfacl and getfacl. Use setfacl to change the default acl for a directory:

    setfacl -d -m o:r foo
    

    -d sets default, -m modifies acl, and o:r grants "other" the right to read. Setting default on a directory is roughly equivalent to setting setgid on a directory, but instead of newly created files inheriting the group, they inherit the acl. Together, setgid and acl can be powerful, because you can grant default permissions to a group, and get newly created files to belong to that group, for an effective group-based per-directory umask.

  4. Check your work: ls -l should now show an extra "+" indicating the presence of acl in addition to the standard file permissions.

    % ls -la foo/
    drwxr--r--+
    

    You can get detailed info on the acl using getfacl.

    % getfacl foo
    # file: foo
    # owner: you
    # group: you
    user::rwx
    group::r--
    other::r--
    default:user::rwx
    default:group::---
    default:other::r--
    

You could also force an umask for the directory by setting the mask ACL-property like this:

setfacl -d -m mask:07 .