15

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?

stickmangumby
  • 526
  • 2
  • 5
  • 11
  • You didn't try googling "umask per directory", did you? If I had the permissions, I'd downvote you for this, because the third hit is a bash hack to do exactly what you want (granted, only for YOU, not for other users.) – Brett Dikeman Jan 12 '12 at 05:48
  • 3
    @BeeDee I did see that. I'm interesting in other ways to do it, hopefully using ACLs. I'd rather not check/change my umask on every cd, or override bash functions. – stickmangumby Jan 12 '12 at 07:40

2 Answers2

20

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--
    
ctrl-alt-delor
  • 149
  • 1
  • 13
user67641
  • 1,242
  • 2
  • 14
  • 18
  • 1
    This doesn't seem to be working for me. `setfacl` and `getfacl` are returning the expected output, but only directories (not files) within the parent directory are inheriting the acl, and even then my umask is taking precedence over the default (if they aren't world readable, the `default:other::r--` doesn't let another user access them). Have I missed something obvious? – stickmangumby Feb 15 '12 at 23:24
  • One thing I've found (perhaps this is the trouble): the facl seems to use the first of (user, group, other) which the current user matches. That is, if you belong to the group for the file, the acl for group will be processed, not the acl for other. The acl should still be inherited if you applied the directory with -d, though.... – user67641 Feb 16 '12 at 02:43
  • 2
    Hm, just tried it again and everything worked fine. Sorry, not sure what I did wrong the first time! Thanks :) – stickmangumby Feb 16 '12 at 20:08
3

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

setfacl -d -m mask:07 .
Saustrup
  • 1,183
  • 1
  • 8
  • 12