На коробке xubuntu у меня есть следующий скрипт, чтобы PHP создавал каталоги, принадлежащие моему пользователю:
<?php
if(!isset($_REQUEST['path'])) die('No path specified');
$path = $_REQUEST['path'];
$res1 = shell_exec("sudo mkdir -p $path");
$res2 = shell_exec("sudo chown -R majid:majid $path");
var_dump($res1, $res2);
?>
Сценарий находится в /var/www/path/to/mkdir.php
Я также добавил этот файл в /etc/sudoers.d/grantmkdir
со следующим содержанием:
www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/mkdir.php
я имею chmod
отредактировал файл 0440
также. Получая доступ к mkdir.php из браузера, вывод NULL NULL
для вар дампов и никакой каталог не создается. Что я делаю неправильно?
Ваша настройка немного запуталась.
Когда вы получаете доступ к этому скрипту из вашего браузера, apache запускает его с пользователем www-data.
Судо не выполняется. Вы не можете заставить apache вызывать ваши скрипты через sudo.
Вы должны обернуть свой чувствительный скрипт в вызов sudo.
Например, таким образом:
Создайте два сценария. Первый будет вызван apache, а второй будет вызван первым через sudo.
first.php:
<?php
if(!isset($_REQUEST['path'])) die('No path specified');
$path = $_REQUEST['path'];
// By the way here you should verify the path! Otherwise malicious users can make your system execute whatever they want...
shell_exec("sudo /var/www/path/to/second.php " . $path);
?>
second.php
#!/usr/bin/php
<?php
shell_exec("sudo mkdir -p " . $argv[1]);
shell_exec("sudo chown -R majid:majid " . $argv[1]);
?>
И сделать second.php исполняемым через sudo:
/etc/sudoers.d/second
www-data ALL=(ALL:ALL) NOPASSWD: /var/www/path/to/second.php
Таким образом, apache запустит first.php, который запустит second.php с помощью sudo.
Вы можете проверить, хорошо ли работают настройки sudo, войдя на ваш сервер, переключитесь на www-data (su www-data). И запустить скрипт вручную.
Несколько примечаний:
Замечания:
This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution
сбои при использовании этой функции. exec () следует использовать при доступе к
Требуется код выхода из программы.
Других решений пока нет …