Мне нужно иметь возможность изменять пароль пользователей через веб-страницу (в контролируемой среде). Итак, для этого я использую этот код:
<?php
$output = shell_exec("sudo -u dummy passwd testUser testUserPassword");
$output2 = shell_exec("dummyPassword");
echo $output;
echo $output2;
echo "done";
?>
Моя проблема в том, что этот сценарий не меняет пароль для пользователя «testUser». Что я делаю не так?
Спасибо






Я недостаточно знаком с PHP, чтобы рассказать вам, как это исправить, но ваша проблема в том, что две команды shell_exec полностью разделены. Похоже, что вы пытаетесь использовать вторую команду для перенаправления ввода первой, но это невозможно. Первая команда не должна возвращаться до тех пор, пока этот процесс не будет выполнен, когда вы запустите вторую, она попытается запустить программу dummyPassword, которая, вероятно, потерпит неудачу.
Используйте proc_open, который позволит вам взаимодействовать со стандартным вводом процесса.
См., В частности, этот комментарий в руководстве: http://www.php.net/manual/en/function.proc-open.php#58044
Первый ответ правильный. Вероятно, вы захотите использовать popen() или какую-либо другую функцию, которая будет возвращать канал, в который вы можете писать так же, как файл, открытый с помощью fopen() или file().
<?php
$pipe = popen("sudo -u dummy passwd testUser testUserPassword", 'r');
fwrite($pipe, "dummyPasswd\r\n");
pclose($pipe);
echo "done";
?>
Я не тестировал это, но это общее представление о том, к чему вы, похоже, стремитесь. Вы заметите, что эта настройка не обеспечивает вывода выполняемых вами команд. Для этого вам понадобится proc_open(), с которым немного сложнее работать, но он обеспечивает двунаправленную поддержку.
Я вообще не заставил этот метод работать. Даже если режим popen должен быть 'w', а команда passwd написана правильно.
Другой вариант - иметь сценарий оболочки, скажем, passwd_change.sh где-нибудь, который выглядит так:
#!/usr/bin/expect -f
set username [lindex $argv 0]
set password [lindex $argv 1]
spawn passwd $username
expect "(current) UNIX password: "
send "$password\r"
expect "Enter new UNIX password: "
send "$password\r"
expect "Retype new UNIX password: "
send "$password\r"
expect eof
Затем в вашем php-коде выполните:
<?php
shell_exec("sudo -u root /path/to/passwd_change.sh testUser testUserPass");
?>
Согласно вашему текущему коду, не будет ли сценарий пытаться отправить их новый пароль в качестве текущего пароля? Это не имело бы смысла, если бы пользователь не установил свой новый пароль таким же, как его старый пароль ...
Кроме того, этот сценарий не работает, потому что при вызове passwd с использованием root он не запрашивает у пользователя root текущий пароль.
Тем не менее, этот метод работает, несмотря на неправильный код. Ubuntu, по крайней мере, не примет старый пароль к новому, что в любом случае не имеет смысла. Немного измените сценарий, и он заработает.
Используйте chpasswd:
$tmpfname = tempnam('/tmp/', 'chpasswd');
$handle = fopen($tmpfname, "w");
fwrite($handle, "$username:".crypt($password)."\n");
fclose($handle);
shell_exec("sudo sh -c \"chpasswd -e < $tmpfname\"");
Остерегаться! Если кто-то получит контроль над $ username, он сможет изменить любой пароль в системе.
Ваше решение действительно выглядело неплохо, но в моей системе unix нет команды chpasswd. Все равно спасибо
Вы должны использовать функцию крипта () для шифрования пароля. Затем вы можете вызвать программу usermod, например, usermod --password username encryptedpassword.
Наиболее распространенный способ шифрования пароля для входа в UNIX выглядит следующим образом:
crypt('password', '$salt1234$')
(Where salt1234 - это восьмибуквенная соль)
Я знаю простой и работающий (по крайней мере, для Debian 4.0r5):
#!/bin/bash
USER = "root"
NEWPASS = "bullsheit123"
echo $USER:$NEWPASS | chpasswd
echo $?
Просто адаптируйте это к скрипту php, и он должен работать нормально.
Слишком поздно, но это для людей, которые все еще ищут ответ. Это то, что мы используем. Чрезвычайно просто.
file_put_contents("passd", "$pass\n$pass\n");
echo "$uname: $pass\n";
`passwd $uname --stdin < passd`;
`rm -rf passd`;
Я предпочитаю использовать 2 отдельных процесса: http://sylnsr.blogspot.com/2012/09/keep-unix-password-in-sync-with.html
Помимо неправильного метода доступа к оболочке, как и все ответы, которые пытаются разрешить, команда passwd неверна. По крайней мере, в моей книге вы не можете просто написать новый пароль таким образом в командной строке.