Force all files & subdirs that BY ANY MEANS come to be in/under a directory to inherit all permissions and group
I know this question may appear to be a duplicate, because many people have asked related questions about permission inheritance. However, none of the answers I've found address the full scope of what I'm trying to accomplish, so here goes:
I have a "share" directory, on an ext4 filesystem on Debian stable, which contains subdirectories belonging to different users. Each user should have Read access to everything in the entire tree, and Read-Write access to their own sub-tree. The users are free to add files to their own sub-tree, and those files originate from an endless variety of sources I have no control over, so their existing permissions are inconsistent garbage that can be discarded without hesitation.
Thus far, I have created a "share" group and added the relevant users to it, then chown -R
set the group ownership to that "share" group and chmod -R
set the desired permissions... for all the files that are already in there. Using the SetGID bit, I can propagate the group ownership to newly created files, and using the "default" capability of Posix ACLs I can similarly propagate permissions to newly created files.
But! If an existing file is moved into the "share" directory tree from elsewhere, its existing GID and permissions/ACL take precedence and none of the above has any effect whatsoever. I understand that there are good and important reasons why this is the normal default behaviour of the filesystem (principle of least surprise, user-set permissions are generally chosen for a reason, etc.)... But in this case, for this particular directory tree, I want to override that behaviour.
I want to consistently, as promptly as possible (by force if necessary) apply a set of permissions and group ownership to all files, directories, and symlinks that come to be located in this directory tree, whether they get there by creation, move, copy, rsync, scp, unzip, untar, teleportation, orbital-drop, spontaneous quantum event, or any other means whatsoever.
I am root on this machine, and am willing to consider alternative filesystems, though only mature, production-ready filesystems that are well supported by Linux will be considered as candidates.
So far, the least awful way I can see to achieve this objective is to run some sort of inotify watcher (Watchman, maybe) as an always-on systemd service, to watch the whole tree recursively and call a script to chown and chmod files whenever the watcher detects changes. This is better than a timed job to blindly run chown -R
and chmod -R
over and over again, but it's still a crude and inefficient approach. Before I start implementing that ugly workaround, I'm really hoping somebody out there knows of a built-in capability of ext4 or some other applicable filesystem to handle this in an efficient and native way.
Solution 1:
I'm not saying this is impossible, but I will say it is highly unlikely that Linux will support a solution like this. It has to do with how the file-system stack works. But first, a bit of history.
Novell netware (late 1980s to mid 2000s depending on what you count as as the death date) had a filesystem with a nice feature that supported exactly this. If you had a directory structure like A -> B -> C ->D
and set a permission on B
, that automatically and immediately applied to C
and D
. This was possible because the file-system was written to made ancestor queries extremely fast; when someone opened a file, it could quickly traverse the entire tree to [root]
and build the effective rights model to make the allow/disallow decision. This made file-system operations a bit heavier than they were for simpler models like those who had posix compliance.
The windows ntfs file-system doesn't do it that way. When you set a permission on B
it then descends the entire tree under B
to apply appropriate permissions on every file and directory. This can and does take hours if you need to end up touching tens or hundreds of millions of files. For new files created below B, the permissions on the immediate directory are used to determine what the file gets.
Now, for linux we have more of the Windows model. File operations look at the file object and the immediate directory and make the allow/disallow decision based on the attributes there without regard for the state of permissions of any other objects. This makes file operations extremely fast, unlike NetWare.
In Linux posix ACL enforcement happens in the VFS layer, which is above the specific filesystems like ext4, xfs, and btrfs. The changes you would need to make to turn a Linux filesystem into the Windows model, where changes above cascade down, would require a custom-built daemon to monitor ACL changes for any directory on the interesting filesystem and cascade the changes downward. But also catch any new file, or change-acl events on any file inode and enforce the 'correct' version. This is not a standard setup, and would have to happen entirely in userspace (probably as a FUSE filesystem).
The Linux VFS layer is highly unlikely to support the NetWare model of rights for two big reasons:
- That's not Posix.
- It makes all file accesses slower, which people hate.
So, yes. You've found the one solution to this problem: do it all in userspace.
I spoke too soon. It turns out that Novell's Open Enterprise Server (OES) is still around and has managed to do just this. For access from a user on the server, such as through SSH or an application running on the server, the user needs to be present in eDirectory (OES's authentication database) and accessing an NSS volume bypasses the Posix layer entirely. The eDirectory presence is required to determine what rights the user will have on the NSS volume.
From an architecture standpoint, Novell/MicroFocus wrote kernel modules to make all of this work. No, they have not shared them under a permissive license. OES is a paid product for just this reason.