2

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.

John Hunt
  • 428
  • 3
  • 10
  • 20

5 Answers5

6

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

Daniel Lawson
  • 5,476
  • 22
  • 27
  • Definitely the most correct way to achieve this but since the OP specifies shared hosting they're at the mercy of their ISP to have ACLs enabled on the server filesystem. – James Yale Jan 13 '11 at 08:30
  • @James: I'll let the OP clarify, but I interpret his question as them having multiple vhosts/customers sharing a server. You may be right though. – Daniel Lawson Jan 13 '11 at 09:03
  • This is indeed being run on shared hosting in this case, but I also admin a VPS so this information is of value to me and will almost certainly be very useful for many people. A thousand thank yous! – John Hunt Jan 14 '11 at 21:19
  • @John: symcbean's solution will also work for you, and may be less impact than enabling ACLs on your filesystem. You're new to serverfault, can you please accept one of our answers and upvote when you decide which you prefer :) – Daniel Lawson Jan 14 '11 at 22:09
1

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.

symcbean
  • 21,009
  • 1
  • 31
  • 52
  • ACLs are dangerous? I guess to someone who doesn't know how to use them, but that's not the ACL's fault, is it? In the right hands, they are not dangerous at all. – churnd Jan 13 '11 at 13:15
  • @symcbean: when a file is uploaded via a website, the files ownership will be that of the user of the webserver, which is not the user the OP is using to manage the site. I guess. :). – Daniel Lawson Jan 13 '11 at 19:13
  • Also, care to elaborate on ACLS being dangerous? If you mean something like "you can accidentally screw up permission for everything on the filesystem if you use them wrong", well, sure, they're dangerous. So is using rm, or using a can opener for that matter. That said, group sticky bit, although being less flexible, will probably work as well as acls. – Daniel Lawson Jan 13 '11 at 19:15
  • > 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. By this I meant that new files created by a php script are then owned by apache. Sorry, this wasn't very clear. – John Hunt Jan 14 '11 at 21:20
  • And yes, I'm well aware of how insecure FTP is, but then that's the only method of access to these sites. These are legacy sites and we're slowly moving things over to VPS-es etc.. – John Hunt Jan 14 '11 at 21:23
  • @John setting the permission g+s on the directories, also called the group sticky bit sometimes, will probably also solve your problem. You'll also need g+w of course, in order to change anything. This will cause group membership to be propagated into any new files and directories (so you'll need to do a recursive set once). In short: new files will be created by the webserver as members of a different group, one which you can assign to the admin users to let them do their tasks. – Daniel Lawson Jan 14 '11 at 22:08
0

The only way I've ever solved this sort of problem is to have root running a regular cronjob which sets the permissions on the files in the webserver directory. That's kind of ugly but it works ok.

Phil Hollenback
  • 14,947
  • 4
  • 35
  • 52
0

You can make use of the umask setting for apache.

http://www.cyberciti.biz/tips/understanding-linux-unix-umask-value-usage.html

By default files uploaded using Apache will interit the umask setting of the server.

But you have the option to set umask specifically for Apache.

Check out this https://stackoverflow.com/questions/428416/setting-the-umask-of-the-apache-user

nitins
  • 2,579
  • 15
  • 44
  • 68
0

Instead of running cronjobs to change ownership, you could use fsniper: http://freshmeat.net/projects/fsniper

fsniper monitors directories for new files (through inotify) and triggers scripts instantly instead of periodically.

sa_zh
  • 11
  • 1