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 is ourgroup.
  • Only people in the ourgroup group can access group_dir.
  • user1 and user2 belong to ourgroup.
  • 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 inside group_dir (but not deeper).
  • Anyone who's not in ourgroup will be blocked at group_dir, and will therefore be unable to manipulate anything under it. For instance, user3 (who isn't a member of ourgroup), cannot read group_dir/user2_submission/README (even though he has r-- 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:

  1. 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.

  2. 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.