Forcing owner on created files and folders
Setting a default owner "automatically" would require a directory setuid
behaving like setgid
. However, while this can be configured on FreeBSD, other UNIX & Linux systems just ignore u+s
. In your case however, there might be another solution.
What I want is to have a directory that can be shared by adding a group to a user. Anything created in this directory inherits the permission scheme from its parent. If there is a better way than what I’m attempting, I’m all ears.
So, basically, from what I see, you want to control the access to a directory using the groups mechanism. However, this does not require you to restrict the permissions in the whole directory structure. Actually, the directory --x
execution bit could be just what you need. Let me give you an example. Assuming that...
- The group controlling the access to the
group_dir
directory isourgroup
. - Only people in the
ourgroup
group can accessgroup_dir
. user1
anduser2
belong toourgroup
.- The default umask is 0022.
... consider the following setup:
drwxrws--- root:ourgroup |- group_dir/
drwxr-sr-x user1:ourgroup |---- group_dir/user1_submission/
drwxr-sr-x user2:ourgroup |---- group_dir/user2_submission/
-rw-r--r-- user2:ourgroup |-------- group_dir/user2_submission/README
Here, let's assume every item was created by its owner.
Now, in this setup:
- All directories can be browsed freely by everyone in
ourgroup
. Anyone from the group can create, move, delete files anywhere insidegroup_dir
(but not deeper). - Anyone who's not in
ourgroup
will be blocked atgroup_dir
, and will therefore be unable to manipulate anything under it. For instance,user3
(who isn't a member ofourgroup
), cannot readgroup_dir/user2_submission/README
(even though he hasr--
permission on the file itself).
However, there's a little problem in this case: because of the typical umask, items created by users cannot be manipulated by other members of the group. This is where ACLs come in. By setting default permissions, you'll make sure everything's fine despite the umask value:
$ setfacl -dRm u::rwX,g::rwX,o::0 group_dir/
This call sets:
- Default
rw(x)
permissions for the owner. - Default
rw(x)
permissions for the group. - No permissions by default for the others. Note that since the others can't access
group_dir
anyway, it does not really matter what their permissions are below it.
Now, if I create an item as user2
:
$ touch group_dir/user2_submission/AUTHORS
$ ls -l group_dir/user2_submission/AUTHORS
rw-rw---- user2:ourgroup group_dir/user2_submission/AUTHORS
With this ACL in place, we can try rebuilding our previous structure:
drwxrws---+ root:ourgroup |- group_dir/
drwxrws---+ user1:ourgroup |---- group_dir/user1_submission/
drwxrws---+ user2:ourgroup |---- group_dir/user2_submission/
-rw-rw----+ user2:ourgroup |-------- group_dir/user2_submission/README
Here again, each item is created by its owner.
Additionally, if you'd like to give a little bit more power/security to those using the directory, you might want to consider a sticky bit. This would, for instance, prevent user1
from deleting user2_submission
(since he has -w-
permission on group_dir
) :
$ chmod +t group_dir/
Now, if user1
tries to remove user2
's directory, he'll get a lovely Operation not permitted
. Note however that while this prevents directory structure modifications in group_dir
, files and directories below it are still accessible:
user1@host $ rm -r user2_submission
Operation not permitted
user1@host $ > user2_submission/README
user1@host $ file user2_submission/README
user2_submission/README: empty (uh-oh)
Another thing to take into account is that the ACLs we used set up default permissions. It is therefore possible for the owner of an item to change the permissions associated to it. For instance, user2
can perfectly run...
$ chown g= user2_submission/ -R
or
$ chgrp nobody user2_submission -R
... hence making his full submission directory unavailable to anyone in the group.
However, since you're originally willing to give full rws
access to anyone in the group, I'm assuming you're trusting these users, and that you wouldn't expect too many malicious operations from them.
There is a smarter way to do this. It uses a combination of set-gid and default acls. Obviously, you will need an acl enabled file system. Let's assume the directory you want shared is at /var/grpdir
and that members of group sharing
should be able to access it.
chown root:sharing /var/grpdir
chmod 2770 /var/grpdir #other can't read or traverse into the directory, set-gid is set
setfacl -d -m u::rwX,g::rwX,o::0 /var/grpdir
Default ACLs are inherited by subdirectories created in a directory with default ACLs. So this means, any file created in /var/grpdir
will have it's group set to sharing
by the directory's setgid bit. Additionally, it will inherit the default acls, which will override the default linux style premissions, because we didn't specify ACLs with specific users or groups. This means all files will be created with ownership <user>:sharing
and permissions rw-rw----
. Directories will be the same, except they will also have their own default ACLs set to the same as their parent (/var/grpdir
), and of course have the executable bits set for user and group. If you remove a user from the sharing
group, they won't be able to access the directory (nor any files in it, even if they own them).
Unlike periodically correcting permissions with a cronjob, permissions are always in sync, as they are updated atomically with newly created files and directories. This solution is lightweight; no daemons are necessary, and there's no spike to IO whilst correcting permissions in one fell swoop.
I am not aware of any good way to do this. The technically cleanest way would be a FUSE file system which does that. Of course, a lot of work if nobody has done that yet.
Alternatives:
Use samba. samba has the
force user
parameter. You can export a directory locally and mount it locally. Doesn't make accesses faster but may be acceptable as only loop back networking is involved.Use a non-Linux file system like FAT32. This must be configured for a certain user to mount it. The access permissions must be handled by the parent directory.