Inheriting file ownership on linux

We have an ongoing problem here at work. We have a lot of websites set up on shared hosts, our cms writes many files to these sites and allows users of the sites to upload files etc..

The problem is that when a user uploads a file on the site the owner of that file becomes the webserver and therefore prevents us being able to change permissions etc via FTP.

There are a few work arounds, but really what we need is a way to set a sticky owner if that's possible on new files and directories that are created on the server. Eg, rather than php writing the file as user apache it takes on the owner of the parent directory.

I'm not sure if this is possible (I've never seen it done.) Any ideas?

We're obviously not going to get a login for apache to the server, and I doubt we could get into the apache group either.

Perhaps we need a way of allowing apache to set at least the group of a file, that way we could set the group to our ftp user in php and set 664 and 775 for any files that are written?

Cheers, John.


Solution 1:

POSIX ACLs will let you set inheritable ACLs. If you set the default acl for a directory, this is inherited down the stack as new files are created.

$ sudo mkdir /tmp/acltest
$ ls -ld /tmp/acltest 
drwxr-xr-x 2 root root 4096 2011-01-13 20:39 /tmp/acltest
$ touch /tmp/acltest
touch: setting times of `/tmp/acltest': Permission denied

At this point my user (daniel) can't create files in this directory. I set the default acl for the directory, as well as setting a user acl on the top directory (the default applies to files/directories created in this directory, not to the actual directory itself)

$ sudo setfacl -m d:u:daniel:rwx /tmp/acltest/
$ sudo setfacl -m u:daniel:rwx /tmp/acltest/

And now, I can create a file:

$ touch /tmp/acltest/foo
$ ls -la /tmp/acltest/foo 
-rw-r--r-- 1 daniel daniel 0 2011-01-13 20:41 /tmp/acltest/foo

Additionally, I can do anything I like to files that other users create in this directory:

$ sudo mkdir /tmp/acltest/foo2
$ ls -ld /tmp/acltest/foo2
drwxrwxr-x+ 2 root root 4096 2011-01-13 20:49 /tmp/acltest/foo2
$ sudo touch /tmp/acltest/foo2/bar
$ ls -la /tmp/acltest/foo2/bar 
-rw-rw-r--+ 1 root root 0 2011-01-13 20:43 /tmp/acltest/foo2/bar

Normal unix permissions won't let me touch this, however ACLs say otherwise:

$ getfacl /tmp/acltest/foo2/bar
# file: tmp/acltest/foo2/bar
# owner: root
# group: root
user::rw-
user:daniel:rwx         #effective:rw-
group::r-x          #effective:r--
mask::rw-
other::r--

Note that this file is inside a subdirectory of the /tmp/acltest directory, and so normal unix permissions wouldn't let me do anything with this file.

And indeed, the user daniel can do whatever they like to this file:

$ mv /tmp/acltest/foo2/bar /tmp/acltest/foo2/bar2
$ ls -la /tmp/acltest/foo2/
total 8
drwxrwxr-x+ 2 root root 4096 2011-01-13 20:49 .
drwxrwxr-x+ 3 root root 4096 2011-01-13 20:43 ..
-rw-rw-r--+ 1 root root    0 2011-01-13 20:43 bar2

Note that the default acls will only propagate as new files and directories are created. You'll need to do a recursive set operation once to set everything in place, then after that your default acl will take over.

In order to user acls, you'll need to make sure your filesystem is mounted with the acl option in /etc/fstab.

TL;DR POSIX ACLs will allow you to set sticky user/group permissions that propagate down a filesystem tree.

EDIT: Formatting and mount option

Solution 2:

acls are potentially very dangerous - and support varies. A better solution would be to use the group sticky bit and making files writeable by the group.

The problem is that when a user uploads a file on the site the owner of that file becomes the webserver and therefore prevents us being able to change permissions etc via FTP.

That doesn't make any sense - how can a user become a webserver? Or are you trying to describe what's happenning with PHP safe_mode with gid checking disabled? In which case the solution is probably to use sticky group bit with safe_mode_gid, however the safe_mode functionality is deperecated and you should be looking for a different solution which does not depend on it.

a lot of websites set up on shared hosts

Do you have root access to the hosts? If not then you should defnitely consider migrating to a dedicated or virtual host where you can actually control these things - if you can't change the config, then your only option is to use shared accounts.

You should also move on from using FTP - it's a security nightmare and is very difficult to automate.