Cron – apache-user & root access

apache-2.2cronphp5root

I want to develop few scripts in php that will invoke following commands; using exec() function

service network restart

crontab -u root /xyz/abc/fjs/crontab

etc.

The issue is that Apache executes script as apache user (I am on CentOS 5), regardless of adding apache into wheel or doing good, the bad and the ugly group assignment does not run commands (as mentioned above).

Following are my configurations;

My /etc/sudoers

root    ALL=(ALL)       ALL
apache  ALL=(ALL)       NOPASSWD: ALL
%wheel  ALL=(ALL)       ALL
%wheel  ALL=(ALL)       NOPASSWD: ALL

As I've tried couple of combination with sudoer & httpd.conf, the recent httpd.conf look something as follows;

my httpd.conf

User apache
Group wheel

my PHP script

exec("service network start", $a);
print_r($a);

exec("sudo -u root service network start", $a);
print_r($a);

Output

Array
(
    [0] => Bringing up loopback interface:  [FAILED]
    [1] => Bringing up interface eth0:  [FAILED]
    [2] => Bringing up interface eth0_1:  [FAILED]
    [3] => Bringing up interface eth1:  [FAILED]
)
Array
(
    [0] => Bringing up loopback interface:  [FAILED]
    [1] => Bringing up interface eth0:  [FAILED]
    [2] => Bringing up interface eth0_1:  [FAILED]
    [3] => Bringing up interface eth1:  [FAILED]
)

Without any surprise, when I invoke restart network services via ssh, using similar user like apache, the command successfully executes. Its all about accessing such commands via HTTP Protocol. I am sure cPanel/Plesk kind of software do use something like sudoer or something and what I am trying to do is basically possible. But I need your help to understand which piece I am missing?

Thanks a lot!

Best Answer

If you take troyengel's solution of throwing an entry in the root cron table, then modify it a little, you might have a workable solution.

If you absolutely, positively need to use apache to signal an interface restart, why not have PHP create a file that acts as a flag, and then have your root cronjob that runs every minute (or whatever) check for the existence of that flag. If it exists, restart the interfaces. If it doesn't, die. (remember to have the cronjob remove the flag after it successfully restarts the interface).

This accomplishes the goal (restarting the interface, triggered from apache/php) and circumsteps all of the possible problems involved with granting a web / scripting service root level access.