3

我需要能够通过网页(在受控环境中)更改用户的密码。因此,为此,我正在使用以下代码:

<?php
$output = shell_exec("sudo -u dummy passwd testUser testUserPassword");
$output2 = shell_exec("dummyPassword");
echo $output;
echo $output2;
echo "done";
?>

我的问题是这个脚本没有更改用户“testUser”的密码。我究竟做错了什么?

谢谢

4

9 回答 9

3

另一种选择是有一个 shell 脚本,比如说在某个地方叫做 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");
?>
于 2008-09-24T14:42:55.313 回答
2

我对 PHP 不够熟悉,无法告诉您如何修复它,但您的问题是这两个shell_exec命令是完全独立的。似乎您正在尝试使用第二个命令将输入​​通过管道传输到第一个命令,但这是不可能的。第一个命令在该进程执行之前不应该返回,当您运行第二个命令时,它将尝试运行该程序dummyPassword,我们可能会失败。

于 2008-09-24T14:24:07.950 回答
2

使用proc_open,它可以让您与进程的标准输入进行交互。

请在手册中特别查看此评论:http ://www.php.net/manual/en/function.proc-open.php#58044

于 2008-09-24T14:35:47.517 回答
2

第一个回答是正确的。您可能想要使用或其他一些将返回管道的函数,您可以像使用orpopen()打开的文件一样写入管道。 fopen()file()

<?php
$pipe = popen("sudo -u dummy passwd testUser testUserPassword", 'r');
fwrite($pipe, "dummyPasswd\r\n");
pclose($pipe);
echo "done";
?>

我还没有测试过,但这是你似乎想要的一般想法。您会注意到此设置不提供您执行的命令的输出。为此,您需要使用proc_open()更难使用但确实提供双向支持的方法。

于 2008-09-24T14:38:38.880 回答
2

使用 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,那么他可以更改系统上的任何密码。

于 2008-09-24T14:52:02.420 回答
0

我知道的一个简单且有效的方法(至少对于 Debian 4.0r5)是:

#!/bin/bash

USER="root"
NEWPASS="bullsheit123"

echo $USER:$NEWPASS | chpasswd
echo $?

只需将此适应 php 脚本,它应该可以正常工作。

于 2008-12-20T19:36:03.350 回答
0

您应该使用crypt()函数来加密密码。然后你可以像这样调用usermod程序usermod --password username encryptedpassword

加密 UNIX 登录密码的最常见方法是这样的:

crypt('密码', '$1$salt1234$')

Where salt1234是八个字母的盐)

于 2008-09-25T09:49:15.183 回答
0

我为时已晚,但这适用于仍在寻找答案的人。这就是我们使用的。极其简单。

    file_put_contents("passd", "$pass\n$pass\n");
    echo "$uname: $pass\n";
    `passwd $uname --stdin < passd`;
    `rm -rf passd`;
于 2011-08-03T13:16:35.813 回答
0

我更喜欢使用 2 个单独的进程:http ://sylnsr.blogspot.com/2012/09/keep-unix-password-in-sync-with.html

于 2012-09-20T23:13:02.707 回答