getfaclbut I have always been missing the big picture. Now I got it.
Let me give you an actual example of use. projects.spamt.net is a private hosting server for open source projects of me and my friends. There we have a web site and a repository for each of a number of projects. This data is accessed through ssh accounts. Additionally there are several deamons granting access to different parts of it to the public. We want to avoid data curruption in case of security problems with a daemon. And we want to be able to give less known people the possibility to edit the web site or commit to the repository of one project without having to trust him not to fiddle about the other projects.
With file access control lists this is easily done. Just setup one group per projects and one user per daemon. Then you grant the daemons read access to the repositories and web sites which they serve and you grant each group read and write access for its corresponding repository and web site. Last for every project you add the user of every developer to the corresponding group. That's it.
$ cd /srv/git # the git-deamon may recursively read everything and enter every sub folder $ setfacl -R -m u:git:rx . # the group foo may resursively read and write the repository of the foo project and enter every sub folder $ setfacl -R -m g:foo:rwx foo.git # the user bar is a developer of the foo project $ adduser bar foo
One thing is left: over time new files will emerge and they should have the same access restrictions as the current ones. Thanks to ACLs the time of cron jobs setting all permissions right are over. Instead you can define so called default ACLs. They are properties of directories and control the ACLs of newly created files and directories.
$ cd /srv/git # make sure the git daemon can access newly created files as well $ setfacl -R -d -m u:git:rx . # the same for the foo group and its repository $ setfacl -R -d -m g:foo:rwx foo.git
What is annoying is that the machanism of default ACLs does not work for files which are moved from somewhere else. Instead those files keep theire ACLS
/tmp/test $ ls /tmp/test $ setfacl -d -m u:alex:rwx . /tmp/test $ touch file /tmp/test $ getfacl --omit-header file user::rw- user:alex:rwx #effective:rw- group::r-x #effective:r-- mask::rw- other::r-- /tmp/test $ touch /tmp/file2 /tmp/test $ mv /tmp/file2 . /tmp/test $ getfacl --omit-header file2 user::rw- group::r-- other::r--
Once I imported an existing repository by first copying it with scp into my home directory and then moving it with root privilidges from there to the git directory. As explained above this broke my security model and left the repository inaccessible for the git daemon. If I had copied it instead everything would have been fine.
/tmp/test $ touch /tmp/file3 /tmp/test $ cp /tmp/file3 . /tmp/test $ getfacl --omit-header file3 user::rw- user:alex:rwx #effective:rw- group::r-x #effective:r-- mask::rw- other::r--
As far as I can see the problem origins from the fact that POSIX file ACLs are not hierarchic. Instead of resursively looking up the parent directory's ACLs in order to decide about granting or denying access only the file's ACLs are considered. And those can be automatically be set at creation time by means of default ACLs. That's it, no more magic.