Using shell_exec('passwd') to change a user's password

11,858

Solution 1

Another option is to have a shell script, say called passwd_change.sh somewhere that looks like this:

#!/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

Then in your php code do:

<?php
shell_exec("sudo -u root /path/to/passwd_change.sh testUser testUserPass");
?>

Solution 2

I'm not familiar enough with PHP to tell you how to fix it, but your problem is that the two shell_exec commands are entirely separate. It appears as though you're trying to use the second command to pipe input to the first one, but that's not possible. The first command shouldn't return until after that process has executed, when you run the second one it will attempt to run the program dummyPassword, which we can probably expect to fail.

Solution 3

Use proc_open, which will let you interact with the process's stdin.

See this comment in particular at the manual: http://www.php.net/manual/en/function.proc-open.php#58044

Solution 4

The first response is correct. You probably want to use popen() or some other function that will return a pipe, which you can write to just like a file opened with fopen() or file().

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

I haven't tested that, but it's the general idea of what you seem to be going for. You'll notice that this setup doesn't provide for the output from the commands you executed. For that, you'll need to use proc_open() which is a little harder to work with but does provide bi-directional support.

Solution 5

Use 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\"");

Beware! If somebody will get control on $username then he can change any password on a system.

Share:
11,858
RSilva
Author by

RSilva

Updated on June 08, 2022

Comments

  • RSilva
    RSilva almost 2 years

    I need to be able to change the users' password through a web page (in a controlled environment). So, for that, I'm using this code:

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

    My problem is that this script is not changing the password for the user "testUser". What am I doing wrong?

    Thanks

  • RSilva
    RSilva over 15 years
    It really looked nice your solution, but my unix system does not have the "chpasswd" command. Thank you anyway
  • Jake Wilson
    Jake Wilson over 12 years
    According to your current code, wouldn't the script try to send their new password as their current password? This wouldn't make sense unless the user was setting their new password to be the same as their old password...
  • Jake Wilson
    Jake Wilson over 12 years
    Also, this script fails because when calling passwd using root, it doesn't ask the root user for the user's current password.
  • Robin Manoli
    Robin Manoli about 11 years
    This method works nonetheless, despite the code being wrong. Ubuntu at least will not accept the old password to the new, a change which makes no sense anyway. Alter the script a bit and it works.
  • Robin Manoli
    Robin Manoli about 11 years
    I didn't get this method to work at all. Even if the mode of popen should be 'w', and the passwd command written correctly.