Как проверить, какой пользователь php работает?
Мне нужно определить, работает ли php как никто. Как мне это сделать? Есть ли другие имена для «никто»? «Апач»? Любые другие?
Что вы имеете в виду именно под вопросом «есть ли другие имена»? Системные администраторы могут создавать пользователей с любым именем, которое они хотят.
Любые другие имена по умолчанию для всего, что может считаться сервером; apache, nobody, www-data и т.д ..
Если я правильно помню, пользователи системы обычно имеют маленький UID (ниже 1024?). Это может быть лучшим ключом к тому, чего вы пытаетесь достичь.
get_current_user () возвращает владельца текущего скрипта, а не пользователя php, запущенного в данный момент.
12 ответов
Если доступно, вы можете исследовать текущую учетную запись пользователя с помощью posix_geteuid а затем получить имя пользователя с помощью posix_getpwuid .
$username = posix_getpwuid(posix_geteuid())['name'];
Однако, если вы работаете в безопасном режиме (что часто бывает, когда exec отключен), то маловероятно, что ваш PHP-процесс работает под чем угодно, кроме учетной записи www-data или apache по умолчанию.
На get_current_user() есть комментарий , демонстрирующий этот подход. Начиная с PHP 5.4 его можно сократить до следующего: print posix_getpwuid(posix_geteuid())[‘name’];
Это может быть полезно для некоторых пользователей: если вы запустите это из интерфейса командной строки, вы получите пользователя, который запускает команду, а не пользователя PHP.
@BramVanroy — я хочу понять ваш комментарий, но я не понимаю. если вы запускаете это из cli, разве вам не принадлежит текущий процесс php? Кем бы в этом случае был пользователь PHP, кроме вас?
Вид обратного пути, но без exec/system:
file_put_contents("testFile", "test"); $user = fileowner("testFile"); unlink("testFile");
Если вы создадите файл, владелец будет пользователем PHP.
Это также может быть запущено с любой из временных файловых функций, таких как tempnam() , которая создает случайный файл во временном каталоге и возвращает имя этого файла. Если есть проблемы из-за чего-то вроде разрешений, open_basedir или безопасного режима, который предотвращает запись файла, как правило, каталог temp все равно будет разрешен.
Приятно: единственное непривилегированное решение здесь, чтобы также найти группу , под которой работает PHP.
Я не могу писать в веб-каталог, что и привело меня сюда, но вместо того, чтобы оказаться в ловушке круга неудач, я прочитал комментарий Джонатана Куна, и tempnam сработал. Я до сих пор не могу написать в каталог, но, по крайней мере, я подтвердил, кто я.
Зависит от прав записи, php user есть у php user или нет. А для предоставления прав на запись вам необходимо знать имя пользователя, что практически возможно только тем программистам, которые забыли php user после назначения ему прав на запись.
@RavinderPayal Если вы не используете функцию tempnam, как я предложил. Почти гарантировано, что пользователь может писать во временный каталог независимо от того, кто он. Не имея возможности записи во временный каталог, вы можете временно дать папке 777 разрешений и, если включено, отключить selinux для этого пути.
@RavinderPayal есть дополнительные функции для возврата временного пути. Итак, $temp_file = tempnam(sys_get_temp_dir(), ‘TMP’); создаст временный файл во временном каталоге в большинстве систем. Затем вы можете использовать этот файл для получения пользователя / группы. Я оставил часть этого на усмотрение пользователя.
Более подробная информация была бы полезна, но если предположить, что это Linux-система, и предположим, что php работает под apache, она будет работать так же, как и любой пользовательский apache, выполняемый как.
Простой способ проверить (опять же, предполагая некоторую среду, похожую на unix) — создать php файл с помощью
который предоставит вам пользователя.
Для моего экземпляра AWS я получаю apache как вывод, когда я запускаю этот script.
Вы можете попробовать использовать обратные такты:
Это может быть полезно для некоторых пользователей: если вы запустите это из интерфейса командной строки, вы получите пользователя, который запускает команду, а не пользователя PHP.
lsof -i lsof -i | less lsof -i | grep :http
любой из них. Вы можете ввести em в свою командную строку ssh, и вы увидите, какой пользователь прослушивает какую службу.
вы также можете пойти и проверить этот файл:
и найдите следующие строки:
export APACHE_RUN_USER=user-name export APACHE_RUN_GROUP=group-name
чтобы отфильтровать данные файла envvars, вы можете использовать grep:
more /etc/apache2/envvars |grep APACHE_RUN_
Это может быть полезно для некоторых пользователей: если вы запустите это из интерфейса командной строки, вы получите пользователя, который запускает команду, а не пользователя PHP.
добавьте файл info.php в следующий каталог — ваш каталог http/apache по умолчанию — обычно /var/www/html
Затем перезапуск httpd/apache перейдите в свой html-каталог по умолчанию http://enter.server.here/info.php
предоставит всю родословную php!
В моей настройке я хочу проверить, разрешено ли текущему процессу создавать папки, вложенные папки и файлы, прежде чем начинать процесс, и предложить решение, если оно похоже на то, что я не могу. Я хотел запустить stat() для разных целей, чтобы обеспечить соответствие разрешений для выполняемого процесса (я использую php-fpm, поэтому он зависит от пула).
Решение, созданное на основе posix, описанное Марио выше, кажется идеальным, однако кажется, что расширение posix —disabled, поэтому я не мог выполнить вышеописанное, и поскольку я хочу сравнить результаты с ответом от запуска stat(), выполняющего whoami в отдельная оболочка тоже не полезна (мне нужны uid и gid, а не имя пользователя).
Однако я нашел полезный намек, я мог stat(/proc/self) и stat(/proc/self/attr) и видеть uid и gid файла.
Надеюсь, что кто-то еще поможет
Предложение
Немного поздно, но, несмотря на то, что следующее является обходным, оно решает требование, поскольку это работает очень хорошо:
"; $process_usr = "apache"; // fall-back if (is_readable("./temp") && is_writable("./temp")) < file_put_contents($native_path,$php_content); $process_usr = trim(file_get_contents($public_path)); unlink($native_path); >return $process_usr; > echo get_sys_usr(); // www-data ?>
Описание
Выделение кода выше неточно, скопируйте и вставьте в свой любимый редактор и просмотрите его как PHP-код или сохраните и протестируйте его самостоятельно.
Как вы, вероятно, знаете, get_current_user() возвращает владельца «текущего запуска script», поэтому, если вы не «chown» a script на сервере для пользователя веб-сервера, он, скорее всего, быть «никому», или если разработчик-пользователь существует в той же ОС, он скорее отобразит это имя пользователя.
Чтобы обойти это, мы создаем файл с текущим запуском процесса. Если вы просто require() в текущем запуске script, он будет возвращать то же самое, что и parent-script, как указано; поэтому нам нужно запустить его как отдельный запрос для вступления в силу.
Процесс потока
Чтобы сделать это эффективным, подумайте о запуске шаблона проектирования, который включает в себя «режим выполнения», поэтому, когда сервер находится в «режиме разработки или в тестовом режиме», тогда только он может запустить эту функцию и сохранить ее выход где-то в include, или просто текст или базу данных, или в зависимости от того, какой из них.
Конечно, вы можете изменить некоторые особенности кода выше, так как вы хотите сделать его более динамичным, но логика выглядит следующим образом:
- определить уникальную ссылку на ограничение помех другим пользователям
- определить локальный путь к файлу для записи временного файла
- определить общий URL-адрес/путь для запуска этого файла в собственном процессе
- напишите временный файл php, который выводит имя владельца script
- получить результат этого script, сделав запрос к нему
- удалить файл, поскольку он больше не нужен — или оставить его, если вы хотите
- возвращает результат запроса в качестве возвращаемого значения функции
exec
Если параметр output указан, то массив будет заполнен строками вывода программы. Завершающие пробелы, такие как \n , не будут включены в массив. Обратите внимание, что если массив уже содержит какие-либо элементы, то exec() добавит новые элементы в конец массива. Если же вы не хотите, чтобы функция добавляла новые элементы в конец, вызовите unset() на этом массиве, прежде чем передать его в exec() .
Если аргумент result_code присутствует вместе с output , тогда статус возврата выполненной команды будет записан в этой переменной.
Возвращаемые значения
Последняя строка из результата команды. Если требуется выполнить команду и получить все данные команды без какой-либо обработки, используйте функцию passthru() .
Возвращает false в случае возникновения ошибки.
Для получения результата выполнения команды, убедитесь, что параметр output инициализирован и используется.
Ошибки
Выдаёт ошибку уровня E_WARNING , если функция exec() не может выполнить команду command .
Выбрасывает исключение ValueError , если параметр command не указан или содержит нулевые байты.
Список изменений
Версия | Описание |
---|---|
8.0.0 | Если параметр command не указан или содержит нулевые байты, функция exec() теперь выбрасывает исключение ValueError ; ранее она выдавала ошибку уровня E_WARNING и возвращала false . |
Примеры
Пример #1 Пример функции exec()
// выводит имя пользователя, от имени которого запущен процесс php/httpd
// (применимо к системам с командой «whoami» в системном пути)
$output = null ;
$retval = null ;
exec ( ‘whoami’ , $output , $retval );
echo «Вернёт статус $retval и значение:\n» ;
print_r ( $output );
?>?php
Результатом выполнения данного примера будет что-то подобное:
Вернёт статус 0 и значение: Array ( [0] => cmb )
Примечания
Если вы собираетесь передавать функции пользовательские данные, используйте функции escapeshellarg() или escapeshellcmd() для того, чтобы пользователи не смогли обмануть систему, запустив произвольную команду.
Замечание:
Если вы собираетесь использовать эту функцию в программе, работающей в качестве демона, убедитесь, что стандартный вывод функции направлен в файл или другой поток, в противном случае PHP зависнет вплоть до конца выполнения программы.
Замечание:
В Windows функция exec() стартует cmd.exe для запуска команды. Если вы хотите запустить внешнюю программу без запуска cmd.exe, то используйте функцию proc_open() с установленной опцией bypass_shell .
Смотрите также
- system() — Выполнить внешнюю программу и отобразить вывод
- passthru() — Выполнить внешнюю программу и отобразить необработанный вывод
- escapeshellcmd() — Экранировать метасимволы командной строки
- pcntl_exec() — Запустить указанную программу в области текущего процесса
- Оператор исполнения
User Contributed Notes 20 notes
This will execute $cmd in the background (no cmd window) without PHP waiting for it to finish, on both Windows and Unix.
function execInBackground ( $cmd ) <
if ( substr ( php_uname (), 0 , 7 ) == «Windows» ) <
pclose ( popen ( «start /B » . $cmd , «r» ));
>
else <
exec ( $cmd . » > /dev/null &» );
>
>
?>
(This is for linux users only).
We know now how we can fork a process in linux with the & operator.
And by using command: nohup MY_COMMAND > /dev/null 2>&1 & echo $! we can return the pid of the process.
This small class is made so you can keep in track of your created processes ( meaning start/stop/status ).
You may use it to start a process or join an exisiting PID process.
// You may use status(), start(), and stop(). notice that start() method gets called automatically one time.
$process = new Process ( ‘ls -al’ );
// or if you got the pid, however here only the status() metod will work.
$process = new Process ();
$process . setPid ( my_pid );
?>
// Then you can start/stop/ check status of the job.
$process . stop ();
$process . start ();
if ( $process . status ()) echo «The process is currently running» ;
>else echo «The process is not running.» ;
>
?>
/* An easy way to keep in track of external processes.
* Ever wanted to execute a process in php, but you still wanted to have somewhat controll of the process ? Well.. This is a way of doing it.
* @compability: Linux only. (Windows does not work).
* @author: Peec
*/
class Process private $pid ;
private $command ;
public function __construct ( $cl = false ) if ( $cl != false ) $this -> command = $cl ;
$this -> runCom ();
>
>
private function runCom () $command = ‘nohup ‘ . $this -> command . ‘ > /dev/null 2>&1 & echo $!’ ;
exec ( $command , $op );
$this -> pid = (int) $op [ 0 ];
>
public function setPid ( $pid ) $this -> pid = $pid ;
>
public function getPid () return $this -> pid ;
>
public function status () $command = ‘ps -p ‘ . $this -> pid ;
exec ( $command , $op );
if (!isset( $op [ 1 ]))return false ;
else return true ;
>
public function start () if ( $this -> command != » ) $this -> runCom ();
else return true ;
>
public function stop () $command = ‘kill ‘ . $this -> pid ;
exec ( $command );
if ( $this -> status () == false )return true ;
else return false ;
>
>
?>