If you’ve ever collaborated with someone on a Linux machine or worked as a system administrator on a multi-user Linux system, chances are you’ve set up shared folders for groups of people to share data. It’s quite easy on Linux. Well, kind of. I mean, you can simply create a group, add relevant users in, and set the shared folder’s owner and permission correctly. However, this approach has a problem: new files and directories created inside a shared folder doesn’t inherit the owner and permission of the shared folder itself. Is there a way to achieve that? Yes. In this post, I would like to talk about how to correctly set up the owner and permission for shared folders once and for all.
The SetGID bit
If you know the basics of Linux, you should know how the Linux permission works. There are 9 bits controlling read (r
), write (w
), and execute (x
) permissions for the owner, the group, and everyone else. Actually, there are 3 more bits. They are the SetUID, SetGID, and Sticky bits. Here I will focus on SetGID because it’s relevant to what we are doing. For more information on those bits, you could refer to this superuser blog post.
The SetGID bit, when set on a directory, is to let the group of new files and directories created in that directory automatically set to the parent directory’s group (i.e. inherit the group).
$ mkdir test
$ chgrp testgroup test
$ chmod g+s test
$ touch test/testfile
$ ls -lh test
total 0
-rw-r--r-- 1 siyuan testgroup 0 Dec 20 14:15 testfile
As shown in the example above, the group of the testfile
file is not siyuan
but testgroup
. Does SetGID solve our problem? Partially. It can inherit the group, but it cannot set the permission.
The Access Control List
You may have heard of umask
which controls the default permission of newly created files and directories. However, it’s not really an ideal solution in this case. First, umask
is bind to the process, not the directory. If you want to use umask
, you need to change the setting on a per-user basis so that they have the right umask
set when logging in. Second, it will affect the file/directory creation behavior on the entire system, not just the directory of interest. It would be tedious, difficult, and error prone to let the user change their umask
whenever they operate under a particular directory and change it back afterwards.
We need a more powerful weapon to achieve what we want, and that is the Access Control List (ACL). ACL is a way to provide more fine-grained access control to files and directories. For example, you can give different users or groups different permissions on the same file. This is much more flexible compared to the traditional Linux permission setting (owner, group, world). More importantly, the permission can be inherited on a directory basis, which is exactly what we want. It’s not supported on all system (see its pre-requisite here), but most of the Linux installations nowadays should support it out of the box.
For example, if we want to grant a group rwx
permissions on a shared folder, we can simply do
$ setfacl -m "g::rwx" testfolder # set permission for the owning group
$ setfacl -m "g:testgroup:rwx" testfolder # set permission for arbitraty group
Now the directory permission will have a +
sign in the end, indicating ACL is enabled. You can check the ACL permission entries with getfacl
$ getfacl testfolder
# file: testfolder
# owner: siyuan
# group: siyuan
user::rwx
group::rwx
group:testgroup:rwx
mask::rwx
other::r-x
To make this permission the “default” permission (i.e. to enable inheritance), use the -d
switch with setfacl
$ setfacl -dm "g:testgroup:rwx" testfolder
$ getfacl testfolder
# file: testfolder
# owner: siyuan
# group: siyuan
user::rwx
group::rwx
group:testgroup:rwx
mask::rwx
other::r-x
default:user::rwx
default:group::r-x
default:group:testgroup:rwx
default:mask::rwx
default:other::r-x
NOTICE: These are two separate
setfacl
commands, you need to run both of them. Running the second one alone only sets the defaults but will not change any existing permissions.
With the default set, we can see that a newly created subdirectory inherited the default ACL settings
$ mkdir testfolder/testsubfolder
$ getfacl testfolder/testsubfolder
# file: testfolder/testsubfolder
# owner: siyuan
# group: siyuan
user::rwx
group::r-x
group:testgroup:rwx
mask::rwx
other::r-x
default:user::rwx
default:group::r-x
default:group:testgroup:rwx
default:mask::rwx
default:other::r-x
Conclusion
In conclusion, the permission and ownership issue on shared folders can be easily solved by applying the SetGID bit together with ACL entries to the folders. With these settings, sharing data among multiple Linux users on the same machine should be hassle-free.