【问题标题】:Using shell_exec('passwd') to change a user's password使用 shell_exec('passwd') 更改用户密码
【发布时间】:2008-09-24 14:20:37
【问题描述】:

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

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

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

谢谢

【问题讨论】:

  • 除了shell访问方法错误,就像所有的答案都试图解决一样,passwd命令是错误的。至少在我的书中,你不能像在命令行上那样写新密码。

标签: php sudo shell-exec passwd


【解决方案1】:

另一种选择是有一个 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");
?>

【讨论】:

  • 根据您当前的代码,脚本不会尝试将他们的新密码作为当前密码发送吗?除非用户将他们的新密码设置为与旧密码相同,否则这是没有意义的......
  • 此外,此脚本失败是因为当使用root 调用passwd 时,它不会向root 用户询问用户的当前密码。
  • 尽管代码错误,但此方法仍然有效。 Ubuntu 至少不会接受新密码的旧密码,无论如何,这种更改毫无意义。稍微修改一下脚本就可以了。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    使用 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”命令。还是谢谢你
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      第一个回答是正确的。您可能想要使用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命令写正确。
      【解决方案6】:

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

      加密 UNIX 登录密码的最常用方法如下:

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

      Where salt1234 是八个字母的盐)

      【讨论】:

        【解决方案7】:

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

        #!/bin/bash
        
        USER="root"
        NEWPASS="bullsheit123"
        
        echo $USER:$NEWPASS | chpasswd
        echo $?
        

        只需将其调整为 php 脚本,它应该可以正常工作。

        【讨论】:

          【解决方案8】:

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

              file_put_contents("passd", "$pass\n$pass\n");
              echo "$uname: $pass\n";
              `passwd $uname --stdin < passd`;
              `rm -rf passd`;
          

          【讨论】:

            【解决方案9】:

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-07-29
              • 1970-01-01
              • 1970-01-01
              • 2013-03-04
              • 1970-01-01
              • 1970-01-01
              • 2023-01-05
              • 2016-10-02
              相关资源
              最近更新 更多