I have a script that executes several commands in a user's home directory. The files are owned by the user and Apache (the www-data
group) only has read privileges to them. The script needs to be executed on demand by PHP via exec()
, and performs some deletions / untarring of files, which fail since Apache doesn't have write permissions to the directories.
I've tried editing the sudoers
file like this :
www-data ALL=(user) NOPASSWD: /bin/su user -c /home/user/bin/script.sh
but it prompts me for the user's password
I've also tried
www-data ALL=(root) NOPASSWD: /usr/bin/sudo su user -c /home/user/bin/script.sh
but that prompts for www-data
's sudo
password
How to I get this to work without a password ?
Finally got it working with this line :
Since I needed arguments to my script, I had to add a "shell-style wildcard" at the end of the line :
It's not exactly what I was looking for, but it works (ie. it happens that my arguments start with alphabetic characters, but in fact I would like the expression to match only alphanumeric characters, dashes and periods).
I'm not at all familiar with shell wildcards and POSIX character classes, the one I use is basically copy-pasted from the sudoers manual. Anyone who knows how these apply to this kind of problem, please leave your comments !
Why are you running su inside sudo? (or worse, sudo inside sudo)
www-data ALL=(user) NOPASSWD: /bin/bash /home/user/bin/script.sh
This should work.
If it weren't a script, you could've just
suid
'd the executable, and set the group & permissions so only the webserver could execute it.You can also use
suExec
(apache only) orCGIWrap
(any webserver) to run CGIs under other users. There's alsosuPHP
specifically for PHP in non-CGI mode on Apache.They offer slightly different options (eg, CGIwrap can set resource limits), but in general, they'll run programs as alternate users.
I've made a different approach to this, to allow the apache user to sudo to a specified user that can then run all commands (or you can specify a list if you only need one or a few.
this allows the password to be sent from code (eg read from database) using :
echo password | sudo -u username -S bash -c command_here arguments_here
Just make sure you use a dedicated user for this, and don't put that user in the wheel group.
see also here
geert