14

I can configure sudo (via the sudoers file) to allow a user to run the chown and chmod commands on any file or directory in the system. However, I only want to grant a user permission to run these commands on files that reside beneath the /var/www/html directory.

How can I restrict privileged commands such that the user may only run them in a pre-specified directory?

For example: The following command grants 777 permissions to index.html file.

sudo chmod 777 /var/www/html/index.html

Now I want to perform two actions

  1. Restrict sudo such that the user may only run chmod and chown from within /var/www/html

  2. Disallow the user from executing these commands elsewhere in the system (e.g. the commands cannot be run in /var/www or /var/ftp)

3
  • 1
    Please don't crosspost - superuser.com/questions/456662/… Aug 2, 2012 at 11:22
  • 7
    Is this really the right way? How about a www-data group eliminating the need to chmod/chown anything?
    – sr_
    Aug 2, 2012 at 11:23
  • Cool. That way you get root pretty easy. It is a very bad idea to give away chown. Apart from that I see no reason why chmod has to be run as root.
    – Nils
    Aug 3, 2012 at 19:38

3 Answers 3

14

What you're asking is difficult if not impossible. Even if you did restrict the application of chown and chmod to files under a specific directory, someone could still pass a symbolic link and so affect files anywhere they like.

Fortunately, it's highly likely that what you're attempting to do is just not the right solution to your actual problem, and there is another method that works.

Usually, users who need additional permissions to create and modify files under /var/www are added to a group (often www-data, or you may have different groups for different parts of the site). You can use group ownership and setgid directories: chgrp www-data /var/www/html; chmod g+ws /var/www/html allows everyone in the www-data group to write to the /var/www/html directory, and files created in that directory will be owned by the www-data group instead of the primary group of the user who created the file. However, this is not very flexible.

What you probably should do is set up access control lists for files under /var/www. First, make sure that ACLs are enabled: the filesystem that /var/www is on must be mounted with the acl option. See Make all new files in a directory accessible to a group for help on that. Also install the ACL utilities (getfacl and setfacl). Then give extra permissions to the tree under /var/www/html to the users who should have them. You can set per-user ACLs, but it's often easier to put users who should have the same rights on a part of the filesystem in a group and set ACLs for that group. For example, if the users in the group html-writers should have read-write access to the tree under /var/www/html:

setfacl -d -m group:html-writers:rwx /var/www/html
setfacl -m group:html-writers:rwx /var/www/html
2
  • Concerning "this is not very flexible" (at the end of paragraph 3) — why is it not? Is it because people need to be in a certain group? (I know barely nothing about permissions and ACL and related things.)
    – KajMagnus
    Aug 14, 2015 at 7:33
  • 3
    @KajMagnus It's inflexible because root has to manage groups, and files can only belong to a single group. ACL let any user select who can access the files they own, and multiple users and groups can be mentioned in an ACL . Aug 14, 2015 at 10:12
3

You can restrict the command to be used by "myuser" with all arguments in /etc/sudoers file with the command visudo add:

## Allows myuser to chmod the html dir and chmod 755 the html2 dir
myuser  ALL=NOPASSWD:/bin/chmod [0-7][0-5][0-5] /var/www/html/*,/bin/chown myuser:mygroup /var/www/html/*,/bin/chmod 755 /var/www/html2/myapp/*.txt 

enable logging for every operation adding:

Defaults logfile=/var/log/sudo.log

sample output:

[root@myhost /]# su - myuser
-sh-3.1$ sudo /bin/chmod 755 /var/www/html/index.html 
-sh-3.1$ sudo /bin/chmod 755 /var/www/html/*
-sh-3.1$ sudo /bin/chmod 777 /var/www/html2/myapp/*.txt
Sorry, user myuser is not allowed to execute '/bin/chmod 777 /var/www/html2/myapp/*.txt' as root on myhost.mydomain.
-sh-3.1$ sudo /bin/chmod 755 /var/www/html2/myapp/*.txt 
-sh-3.1$ 

When you use sudo, the premise should be that "myuser" is a trusted person. Be carefull with file permissions, there is no a simple way to stop a malicious sudo user from link a file from an external resource and change it.

12
  • I have tried it before, but it gave the error as: Sorry, user prashant is not allowed to execute '/bin/chmod 777 /var/www/html/a' as root on prashant.xyz.com.
    – PrashantB
    Aug 2, 2012 at 12:11
  • have you switched user with su - prashant or su prashant?
    – tombolinux
    Aug 2, 2012 at 12:14
  • Yes I am executing command by prashant user. I read forums,they say commands run system-wide. No one has write about such issue.
    – PrashantB
    Aug 2, 2012 at 12:19
  • I run it whooo :). But this will be static command. Can we make it general so that I can apply any permission on any file under /var/www/html?
    – PrashantB
    Aug 2, 2012 at 12:22
  • 5
    This is completely insecure: sudo /bin/chmod 666 /var/www/html/../../../etc/passwd And if you somehow fix that, ln -s /etc /var/www/html/foo/etc; sudo /bin/chmod 666 /var/www/html/foo/etc/passwd Aug 2, 2012 at 23:17
2

There's actually a fairly simple way to do this, by creating a Bash (or shell of your choice) script to restrict the modifications made to a particular file or directory.

In your example, it would look like this:

$ vi /usr/local/bin/mychmod

#!/bin/bash

chmod 777 /var/www/index.html

Then you would change the sudoers file to allow www-data to execute /usr/local/bin/mychmod.

Keep in mind however, that allowing user input (for example, allowing a user to change which file or directory is chmodded) into this space is extremely dangerous, and you need to know how to filter out injection attacks if you want to do anything like that. An attacker could easily execute any command as root this way, effectively compromising the security of your system.

1
  • this is exceptionally dangerous and really doesn't solve the solution...
    – SomeGuy
    Oct 27, 2017 at 14:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .