Debian – Forcing owner on created files and folders

debianfilesystemspermissions

I have a directory that contains data shared between a number of users. Access to this directory and anything underneath, will be controlled by the directory's group, which will be added to the users in question.
As such I created the folder "sticky group" chmod g+s set.
The directory will contain a tree structure with directories and files, with the total amount of files likely being a few million. The files will be fairly small, I don’t anticipate anything bigger than 50MB.

My problem is that the owner of the file or directory is still the user that created it. As such, even if i should remove that user from the access group, I would not remove his access completely.

So:

Are there other options I missed for ensuring that all files and sub-directories have the same owner?

I expect I could periodically surf through the entire directory with a cron-job, but that strikes me as inefficient for what is essentially a once-pr-file command.

I found an example using INotify but that strikes me as high-maintenance, since it requires scripting.

I haven't been able to figure out if ACL can help me with forced ownership.

Is there a smarter way to do this?

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.

Best Answer

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.

Related Question