Giving group permissions to other user’s files

filespermissions

I'm using Debian 7 and have created a new user (website) with an htdocs directory like this:

$ sudo adduser website
$ sudo mkdir -p /home/website/htdocs
$ sudo chown -R website /home/website

Now I'd like users of another group (developers) to have access to the user's directory. I have tried:

$ sudo chown -R :developers /home/website

I can see that the group is assigned (with ls -la or stat) and that the users are in the group, but they don't have access right?

drwxr-xr-x     3     website     developers     4096 May 3 09:09     website

I also want to:

  • Allow another group, 'contractors' access to website files

  • Restrict access of website users to their home directories only

  • Ensure new website files inherit these permissions

Do you have to use access control lists – or is there a better way to do this (like not using a separate user for each site)?

Best Answer

It's hard to give precise commands without knowing the O/S or distribution; and yes! ACL would work, but there's a standard way, too.

There's adduser and useradd, one of them on your distribution may create the user's home directory automatically. If so, then the contents of the /etc/skel/ directory would be copied into the the user's home directory, permissions set, and perhaps some other appropriate actions might make place.

There may exist groups pre-defined for sharing, such as 'staff'; but, if we want to create our own group for sharing, there's nothing wrong with that. So, create a new group or use an existing group. Make sure that users who are to be members of the group have been defined as such with usermod, moduser, or vigr perhaps, according to the operating system. Each user currently logged in must logout and back in again to become a member of a new group.

Create a directory common for all users, such as /home/share_directory/ or any other directory that makes the most sense for your situation. A relevant best practice is not to use a directory within any user's home directory. If no one except the owner and group should be able to see files in the directory, then change the directory's permissions to 0770. If reading is ok by "others", then use 0775. The owner of the directory should almost certainly be root.

chown root:group_name /home/share_directory/

Next, change the setuid bit.

chmod +s /home/share_directory/

If no user should be able to modify another user's file, then also set the stick bit.

chmod +t /home/share_directory/

These examples set both the setuid and sticky bits at the same time using octal notation.

chmod 5775 /home/share_directory/

or

chmod 5770 /home/share_directory/

For the updated question, it seems as though ACL is the right tool. Most Linux distributions now include the acl option in the defaults option. If your distribution doesn't include the acl option by default, then this a little work is needed to start using it. First mount the file systems with the acl option in /etc/fstab.

sudo vim /etc/fstab
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx / ext4 defaults,acl 0 1

If needed, remount the filesystem: sudo mount -o remount,acl /. Then make a group to which a user may belong for this purpose. You may need to install the ACL tools as well: apt-get install acl.

sudo groupadd developers
sudo usermod -a -G developers $username

(Or the group might be "contractors".) A currently logged in user must log out and back in again to become a member of the new group. Of course, do not do this if you have content in the /var/www directory that you want to keep, but just to illustrate setting it up to start:

sudo rm -rf /var/www
sudo mkdir -p /var/www/public
sudo chown -R root:developers /var/www/public
sudo chmod 0775 /var/www/public
sudo chmod g+s /var/www/public
sudo setfacl -d -m u::rwx,g::rwx,o::r-x /var/www/public
sudo setfacl -m u::rwx,g::rwx,o::r-x /var/www/public
sudo setfacl -d -m u::rwx,g:contractors:rwx,o::r-x /var/www/public
sudo setfacl -m u::rwx,g:contractors:rwx,o::r-x /var/www/public

Above, the difference between the setfacl commands are these: the first instance uses the default group (group owner of the directory) while the second specifies a group explicitly. The -d switch establishes the default mask (-m) for all new filesystem objects within the directory. Yet, we also need to run the command again without the -d switch to apply the ACL to the directory itself. Then replace references to "/var/www" with "/var/www/public" in a config file and reload.

sudo vim /etc/apache2/sites-enabled/000-default
sudo /etc/init.d/apache2 reload

If we wanted to restrict delete and rename from all except the user who created the file: sudo chmod +t /var/www/public. This way, if we want to create directories for frameworks that exist outside the Apache document root or maybe create server-writable directories, it's still easy.

Apache-writable logs directory:

sudo mkdir /var/www/logs
sudo chgrp www-data /var/www/logs
sudo chmod 0770 /var/www/logs

Apache-readable library directory:

sudo mkdir /var/www/lib
sudo chgrp www-data /var/www/logs
sudo chmod 0750 /var/www/logs

A litle bit of "play" in a directory that does not matter should help get this just right for your situation.

On restrictions, I use two different approaches: the shell, rssh, was made to provide SCP/SFTP access but no SSH access; or, to restrict the use to a home directory you could use the internal-sftp subsystem, configured in /etc/ssh/sshd_config.

Subsystem sftp internal-sftp

Match group sftponly
  ChrootDirectory /home/%u
  X11Forwarding no
  AllowTcpForwarding no
  ForceCommand internal-sftp

Create a group named, for example, sftponly. Make users a member of the sftponly group. Change their home directories to / because of the chroot. The directory, /home/username, should be owned by root. You can also set the user's shell to /bin/false to prevent SSH access. Mostly I am concerned about interactive access, so generally go with the rssh path. (They can't write anywhere except where I have defined write ability.)