Change Linux or UNIX system password using PHP script

by on August 3, 2006 · 74 comments· LAST UPDATED November 16, 2013

in , ,

If you just wanted to change your own password or other user passwords use passwd command.

I was asked to setup a PHP based interface to change the password. Since my knowledge of php is limited. Here is what I did:

Warning: This is an outdated and insecure information. Please see the official php.net document for more information. You have been warned to ignore this post.

Required tools/setup:

You must have following tools/software installed

=> Shell script to change password

=> Sudo access

=> Apache or Lighttpd web server

=> PHP server side

Step # 1: Setup a shell script to change password

This shell script use expect tool to change the password (see more about expect tool here).

Sample shell script code

#!/bin/sh
# \
exec expect -f "$0" ${1+"$@"}
set password [lindex $argv 1]
spawn passwd [lindex $argv 0]
sleep 1
expect "assword:"
send "$password\r"
expect "assword:"
send "$password\r"
expect eof

You can execute this script as follows (dowload link):
$ chpasswd username password

Download script and copy to your webroot or location where webserver can read this script file:
$ cp chpasswd /var/www/

ALTERNATIVELY, if you are using Ligtttpd web server:
$ cp chpasswd /home/lighttpd

Step # 2: Setup sudo to execute a command as root user

Apache or Lighttpd web server drops root privileges as soon as they go into background. This makes changing password scenario difficult as passwd command needs root privileges to change other user account password.

Typically, Apache 2 use www-data user and Lighttpd use lighttppd username to drop privileges. Login as root user and type the following command:
# visudo

Now allow your web server to execute a script (chpasswd) w/o password. If you are using Apache web server, type the following command:
www-data ALL=NOPASSWD: /var/www/chpasswd

ALTERNATIVELY, if you are using Ligtttpd web server, type the following command:
lighttpd ALL=NOPASSWD: /home/lighttpd/chpasswd

Save and close the file.

Step # 3: Create a PHP based interface

Now you need to write a php script. Here is sample php script. This is a demo script. You should modify it according to your requirement or setup. At minimum, you need to setup correct shell script location so that it will work for you out of box. Open php script and locate line:
$shellscript = "sudo /home/lighttpd/chpasswd";

Change it to point to correct location. PHP Source code:

<?php
// change .. me! - shell script name
$shellscript = "sudo /home/lighttpd/chpasswd";
 
// Make sure form is submitted by user
if(!(isset($_POST['pwdchange']))) {
 // if not display them form
 writeHead("Change password");
 writeForm();
 writeFoot();
}
else {
 // try to change the password
 $callshell=true;
 // get username and password
 $_POST['username'] = stripslashes(trim($_POST['username']));
 $_POST['passwd'] = stripslashes(trim($_POST['passwd']));
 
// if user skip our javascript ...
// make sure we can only change password if we have both username and password
 if(empty($_POST['username'])) {
   $callshell=false;
 }
 if(empty($_POST['passwd'])) {
   $callshell=false;
 }
 if ( $callshell == true ) {
  // command to change password 
  $cmd="$shellscript " . $_POST['username'] . " " . $_POST['passwd'];
  // call command
  // $cmd - command, $output - output of $cmd, $status - useful to find if command failed or not
   exec($cmd,$output,$status);
   if ( $status == 0 ) { // Success - password changed
   writeHead("Password changed");
   echo '<h3>Password changed</h3>Setup a new password';
   writeFoot();
   }
   else { // Password failed 
      writeHead("Password change failed");
      echo '<h3>Password change failed</h3>';
      echo '<p>System returned following information:</p>';
      print_r($output);
      echo '<p><em>Please contact tech-support for more info! Or try <a href='.$_SERVER['PHP_SELF'].'again</a></em></p>';
      writeFoot();
   }
 }
 else {
   writeHead("Something was wrong -- Please try again");
   echo 'Error - Please enter username and password';
   writeForm();
   writeFoot();
 }
}
 
// display html head
function writeHead($title) {
echo '
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> ' .$title. '</title>
<style type="text/css" media="screen">
.passwdform {
	position: static;
	overflow: hidden;
}
 
.passwdleft {
	width: 25%;
	text-align: right;
	clear: both;
	float: left;
	display: inline;
	padding: 4px;
	margin: 5px 0;
}
 
.passwdright {
	width: 70%;
	text-align: left;
	float: right;
	display: inline;
	padding: 4px;
	margin: 5px 0;
}
 
.passwderror {
	border: 1px solid #ff0000;
}
 
.passwdsubmit {
}
</style>
 
</head>
 
<body>';
 
}
// display html form
function writeForm() {
echo '
<h3>Use following form to change password:</h3>
 
<script>
function checkForm() {
if (document.forms.changepassword.elements[\'username\'].value.length == 0) {
    alert(\'Please enter a value for the "User name" field\');
    return false;
}
if (document.forms.changepassword.elements[\'passwd\'].value.length == 0) {
    alert(\'Please enter a value for the "Password" field\');
    return false;
}
  return true;
}
</script>
 
<div class="contactform">
<form action="' . $_SERVER[PHP_SELF]. '" method="post" onSubmit="return checkForm()" name="changepassword">
<div class="passwdleft"><label for="lblusername">User Name: </label></div>
<div class="passwdright"><input type="text" name="username" id="lblusername" size="30" maxlength="50" value="" /> (required)</div>
<div class="passwdleft"><label for="lblpasswd">Password: </label></div>
<div class="passwdright"><input type="password" name="passwd" id="lblpasswd" size="30" maxlength="50" value="" /> (required)</div>
<div class="passwdright"><input type="submit" name="Submit" value="Change password" id="passwdsubmit" />
<input type="hidden" name="pwdchange" value="process" /></div>
</form>
</div>
';
 
}
// display footer 
function writeFoot(){
echo '</body>
</html>
';
}
?>

Step # 4: Run the script

Point a web browser to your server url - https://mydomain.com/changepassword.php. You should see a username and password form as follows:

changepassword php script output # 1

If a password is changed successfully, you should get confirmation as follows:

changepassword php script output # 2

For some reason if a password failed to change, you should get detailed error message as follows:

changepassword php script output # 3

Step # 5: Security

Note this is an example and not final solution as it is little insecure.

  • Never ever run this script over http session. Always run over https session.
  • Put script in a password protected directory (see how to setup Apache or Lighttpd web server password protected directory).
  • Never ever, trust user input. Above php script is just a sample, for real life production you should consider more powerful user input validation. Discussion regarding PHP programming security is beyond the scope of this article. You can consult a good PHP book or search a web using your favorite search engine :)
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 74 comments… read them below or add one }

1 prem August 7, 2006 at 11:50 am

why we need this much pain you can use webmin for easy configuration or some other tools to do this

Reply

2 nixCraft August 7, 2006 at 12:25 pm

Ready to use tools or webmin are not useful for custom-made control panel or other solution. Every situation is different hence; you need to develop your own methods.

No, it is not a pain. We simply call it hacks :P

Reply

3 pipacs August 9, 2006 at 7:34 pm

The expect script proposed here is extremely dangerous. Any user monitoring commands with “ps” could capture user names and passwords.

Reply

4 nixCraft August 9, 2006 at 8:20 pm

Pipacs,

Thanks for your concern. I agree with you. At the movement, this box can be access by admins only and other user change password using above solution.

But if you need to give shell access –
On FreeBSD with secure runlevel prevents other users from monitoring command/script arguments from ps, w, who, top etc commands.

On Linux system you need to apply a special patch to kernel (LINUX BSD LSM) or disable other user shell login all together

If you have any other, solution then please let me know…

Appreciate your post.

Reply

5 chadrick August 9, 2006 at 8:22 pm

Hey, any idea why the expect scriptscript does not works if i remove sleep 1 command :/?

Reply

6 nixCraft August 9, 2006 at 8:31 pm

Chadrick,

As name, suggest sleep command puts pause for NUMBER seconds (1 second). If you are using Debian Linux you need to use sleep to slow down few things. However, on RHEL or CentOS or FreeBSD it works w/o sleep command.

Reply

7 Sven August 10, 2006 at 3:11 pm

passing the POST data straight to a shell is also dangerous. a semicolon in either field, and everything else is executed as a separate command..

See:
http://www.php.net/manual/en/function.escapeshellcmd.php
http://www.php.net/manual/en/function.escapeshellarg.php

Reply

8 Boo August 10, 2006 at 6:50 pm

So, uh, I can just change anyone’s password that I want to? Am I missing something?

username: root
password: owned

Shouldn’t you also at least use SSL or something?

Reply

9 nixCraft August 10, 2006 at 7:05 pm

@Boo, you ssl and Password protected directory is must

@Sven, thanks for link i will update my code!

As I said earlier, my knowledge of php is limited. At the movement, script is protected using SSL and a password-protected directory.

And I must add protection for root user… in php itself

Appreciate all of your posts.

Reply

10 dean September 30, 2006 at 5:02 pm

I am very interested in doing this for a new production process.

Is it possible to have the current password vierified first?

Reply

11 Lars October 2, 2006 at 1:44 pm

thx for the script, very close what i needed quick-and-dirty here, got it up and running for my purpose within 10 minutes.

And yep, its extremely dangerous, but the box running it isn’t designed to be overly safe or even public anyway ^^

Reply

12 elton October 12, 2006 at 6:53 am

I am getting the following error:

spawn passwd
passwd: Only root can specify a user name.

Which makes sense, but how did you not get this?

Reply

13 nixCraft October 12, 2006 at 8:26 am

You need give web server user to change password permission using sudo tool (see step # 2).

Reply

14 Chris November 3, 2006 at 7:44 pm

How can I change this script to add new users ?

Reply

15 nixCraft November 3, 2006 at 11:20 pm

Yes you can. You write a shell script and call same way.

Reply

16 elvis November 6, 2006 at 6:13 pm

As written, this script allows any user’s password to be changed, which may not be a good thing. By placing this script in a secure, password-protected directory, you can avoid having to request the username on the form & instead use the $_SERVER['PHP_AUTH_USER'] variable to get the name of the currently-authenticated user. That will restrict password changes to the authenticated user only.

Reply

17 nixCraft November 6, 2006 at 7:34 pm

elvis,

Good suggestion. I will try to implement them. Yes currently script runs in password protected directory over ssl session.

Appreciate your post.

Reply

18 Fer November 7, 2006 at 6:04 pm

hi,
thank you for sharing your code with us.i want to do the samething but i have to confirm the password first.And this is not working at this point.I think confirming password first needs to edit the shell script at step one.And i dont know about shell scripts.If you have a solution for this problem or anyone knows,please share with us.
thank you again

Reply

19 Ahmad December 20, 2006 at 9:42 am

what we have to do if we want script to match old password first then allow to change the password

Reply

20 jose alfredo December 20, 2006 at 10:04 pm

it doesn`t work on my server,
i keep getting this error message and nothing works whenever i try to print the output array, i get nothig just “Array”, can you help me debug this, sorry about my french

Reply

21 nixCraft December 20, 2006 at 10:41 pm

If you see an array that mean shell script is not working properly. You need to setup correct permission using sudo. What distor and webserver you are using?

Reply

22 jose alfredo December 21, 2006 at 6:48 pm

i am using httpd 2.0.52-22 on a CentOS 4 and i gave both apache and www-data permission to run da script and passwd, but i keep getting nothig but “Array
(
)

Reply

23 Jay Dingenen January 8, 2007 at 8:01 am

I’m having a problem with this script, sometimes if i execute it, it doesn’t return “passwd: all authentication tokens updated successfully.” but i can’t check this from my php so the password isn’t updated and my clients can’t use their ftp logins…
Is it possible to like expect “successfully.” or else restart the script? I haven’t got a clue how to do this so all ideas are welcome.

Reply

24 Herb Perkins-Frederick February 28, 2007 at 10:07 pm

Thanks!

I have a serer running Fedora Core 3. I was having problems with an expect script that I wrote, so I found your site. The chpasswd script worked with one minor modification: instead of “\r” an the end of the send lines, it wanted “\r\n” on my system.

Thanks again!
Herb

Reply

25 Alex March 27, 2007 at 7:33 am

My system is Redhat Linux9.
I try to execute chpasswd script to change password.
But the script didn’t change password successfully.

And I try to open the PHP file.
After I input username and password that also display error message.

=========
Password change failed
System returned following information…..:

Array
(
)

Please contact tech-support for more info! Or try

=========
What can I do and resolve his problem?

Reply

26 שדרך May 18, 2007 at 7:57 pm

Alex,

Try putting the full path to sudo in the php script, that fixed the problem for me:

/usr/bin/sudo

Reply

27 Matt June 1, 2007 at 1:28 pm

I am having the same problem as Alex and I have the full path to sudo in my php script. Any clue?

Reply

28 Matt June 1, 2007 at 2:41 pm

I had to hardcode the command in the $cmd to get it to work

Reply

29 Dan July 5, 2007 at 2:57 pm
30 nixCraft July 5, 2007 at 3:13 pm

Dan,

Good finding.

Appreciate your posts!

Reply

31 Fabian July 13, 2007 at 9:04 pm

Hello
I got this error when I try to run the php script

Parse error: parse error, unexpected T_STRING, expecting ‘,’ or ‘;’ in /srv/www/htdocs/changepassword.php on line 108

here you have line 108
if (document.forms.changepassword.elements['username'].value.length == 0) {

Thanks for your help

Reply

32 Mark July 17, 2007 at 11:24 pm

Fabian — Don’t copy&paste from the site, but use the linked PHP file.

My own question is; where the heck is this spawn command located?! :)

Reply

33 daphne September 11, 2007 at 11:16 am

Couldn’t get this to work using Apache or Lighttpd.

when I browser to localhost://changepassword.php
it just shows a text file of changepassword.php.

Am I doing something wrong?

Reply

34 Sergei September 11, 2007 at 12:41 pm

Dan, http://changepassword.sourceforge.net/ has 35 open bugs and has been abandoned for couple of years now. I think I will stick with Vivek’s scripts

Reply

35 tekhawk September 11, 2007 at 6:53 pm

Could something like this be used on mac server os x as a web based user password reset tool?

Reply

36 Eric October 30, 2007 at 8:49 pm

I’m new to PHP, so don’t expect this to be perfect. It gives me a parse error with the following (very simple) code:

I’m using this to scare the guys in the server room (where we have a Mac Pro).

I don’t even think the syntax is correct either…

Reply

37 Eric October 30, 2007 at 8:51 pm

Why isn’t my code showing?

Reply

38 Steve January 8, 2008 at 8:54 am

This solution involves giving the web user full control over a script that can change any system user’s password, without verification. You might as well just run apache as root.

Reply

39 Liberty Dandira January 28, 2008 at 6:36 pm

Alternatively, without including the shell script

after visudo

Replace www-data ALL=NOPASSWD: /var/www/chpasswd

with

www-data ALL=NOPASSWD: ALL

in your PHP script

just enter

Reply

40 Vijay February 27, 2008 at 8:40 am

Hello everyone,

I need to know how to change linux system time zone using php script.

used this in shell,that is
$ export TZ=MST, then timezone changed to MST,
but i tried this using php script,
that is,

but this is not working.
can anyone tell me what is the reason for this

Reply

41 JimmyJam March 11, 2008 at 2:24 am

When I run the PHP script, I get
sudo: unable to execute /var/www/chpasswd: No such file or directory

My /etc/sudoers contains the following entry
www-data ALL=NOPASSWD: /var/www/chpasswd

I have tested this with permission on /var/www/chpasswd set to 744 and 777 but with no luck.

I call the script from PHP using the following:

// set the user's password
$command = 'sudo /var/www/chpasswd'.
$user_info['username'].' '.
$user_info['password'];
shell_exec($command);

Any help would be greatly appreciated

Reply

42 Tomek Gruca March 20, 2008 at 9:04 pm

pipacs: “The expect script proposed here is extremely dangerous. Any user monitoring commands with “ps” could capture user names and passwords.”

instead of executing “$ chpasswd username password” you can save the password in a tmp file, unreadable for users – that’s what I’ll do ;)

Great script!

Reply

43 Turn fun April 16, 2008 at 3:41 pm

good tool for web server admins ! :)

Reply

44 kevin_cn May 24, 2008 at 5:42 pm

hello
is anyone luck enough?
i have the same problem with 25f’s Alex on arch 27th, 2007 at 7:33 am
i am new to php ,how could i do?
please help!

Reply

45 Stephen W July 14, 2008 at 10:52 pm

The script works with Fedora/CentOS but requires some edits.

As always read the logs!

Check the apache/httpd error logs.

If it states “sudo: sorry, you must have a tty to run sudo”

You will need to comment out “Defaults requiretty” using visudo.

This solution address kevin_cn and Alex’s posts.

Reply

46 arief July 21, 2008 at 6:35 am

i’m trying to do the similar thing to access iptables. my shell script only contains iptables-L, but i still cant run it from my web.
i already change the visudo and adding the “www-data ALL=NOPASSWD: ALL” line.
all im seeing in the error_log is : Permission denied

Reply

47 Olav August 25, 2008 at 5:49 pm

Congratulations on your high Google score with the keywords php+change+linux+password :)

Inspired by your script I decided to make this just a little bit safer by eliminating the need for sudo:

#!/bin/sh
# \
exec expect -f "$0" ${1+"$@"}
set name    [lindex $argv 0]
set curpass [lindex $argv 1]
set newpass [lindex $argv 2]
set chkpass [lindex $argv 3]
spawn su $name -c passwd
sleep 0.5
expect "assword:"
sleep 0.25
send "$curpass\r"
expect "assword:"
sleep 0.25
send "$curpass\r"
expect "assword:"
sleep 0.25
send "$newpass\r"
expect "assword:"
sleep 0.25
send "$chkpass\r"
expect eof

Never mind the many sleep commands in there, but I found that at least it works this way.

Reply

48 Olav August 25, 2008 at 5:50 pm

Err, something went wrong with the code tags there.

Reply

49 nixCraft August 25, 2008 at 5:54 pm

Your comment has been updated. Thanks for contribution.

Reply

50 mangwantong August 28, 2008 at 8:28 am

Hi
After I try to run Step 1 I have some problem
password show change ok but not change realy

I try run below on my sytem
[root@localhost Code]# sh chpasswd admin mvc123
spawn passwd admin
Changing password for user admin.
New UNIX password: mvc123

Retype new UNIX password: mvc123

[root@localhost Code]#

That finish I think it ok
I try to login by name = admin and newpass
login not ok but old password still work
I don’ know why?

my system ES3

Reply

51 dustro August 30, 2008 at 8:55 am

thanks for the code it works for me.

Reply

52 mangwantong September 4, 2008 at 3:15 am

If I use Solaris10 how can I do?
This code can run on solaris?

Reply

53 vinotha September 29, 2008 at 7:23 am

I try to execute chpasswd script to change password.
But the script didn’t change password successfully.

whn i use sh chpassword test test123 its working.

And I try to open the PHP file.
After I input username and password that also display error message.

=========
Password change failed
System returned following information…..:

Array
(
)

Please contact tech-support for more info! Or try

=========
in my /var/log/messages error shown as

authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=apache

What can I do to resolve this problem?

Reply

54 Thuan VU DUC May 5, 2010 at 6:33 pm

Have you try grant execution for the file chpasswd?
chmod +x /var/www/chpasswd
Hope thís help.

Reply

55 Jhon Rodriguez September 2, 2014 at 4:49 pm

Use the function shell_exec in the php script and work fine!

Reply

56 Bollywood January 27, 2009 at 10:51 pm

very help full article keep it up i like it because its full of details….

Reply

57 Terry February 4, 2009 at 5:27 am

I’ve written a function which doesn’t need an external script, and does not need sudo access. This eliminated the concern of someone capturing the password by monitoring ps, and allows everything to be done without the need for external files. A log file is created during the password change procedure, though this does not contain any passwords, it’s used to verify the password being successfully changed, and it’s deleted on completion.

Note: you may need to modify the expect strings, depending on your systems password chat.

function changePassword($user, $currpwd, $newpwd) {
	// Open a handle to expect in write mode
	$p = popen('/usr/bin/expect','w');
	// Log conversation for verification
	$log = '/tmp/passwd_' . $user . '_' . time();
	$cmd .= "log_file -a \"$log\"; ";
	// Spawn a shell as $user
	$cmd .= "spawn /bin/su $user; ";
	$cmd .= "expect \"Password:\"; ";
	$cmd .= "send \"$currpwd\\r\"; ";
	$cmd .= "expect \"$user@\"; ";
	// Change the unix password
	$cmd .= "send \"/usr/bin/passwd\\r\"; ";
	$cmd .= "expect \"(current) UNIX password:\"; ";
	$cmd .= "send \"$currpwd\\r\"; ";
	$cmd .= "expect \"Enter new UNIX password:\"; ";
	$cmd .= "send \"$newpwd\\r\"; ";
	$cmd .= "expect \"Retype new UNIX password:\"; ";
	$cmd .= "send \"$newpwd\\r\"; ";
	$cmd .= "expect \"passwd: password updated successfully\"; ";
	// Commit the command to expect & close
	fwrite($p, $cmd); pclose ($p);
	// Read & delete the log
	$fp = fopen($log,r);
	$output = fread($fp, 2048);
	fclose($fp); unlink($log);
	$output = explode("\n",$output);
	return (trim($output[count($output)-2]) == 'passwd: password updated successfully') ? true : false;
}

Reply

58 Derek May 25, 2009 at 9:45 pm

Terry,

I’ve worked on combining your changePassword function with the original script. Unfortunately this expect script does not gracefully handle the case of a nonexistent user. I get the user’s typed-in password printed (in clear) in my http error_log:

send: spawn id exp16 not open
while executing
“send “xxx\r””

Reply

59 rchilro August 17, 2011 at 8:37 am

if I may suggest, you can replace the end of the script like this:

# send passwd command
send — “passwd $user\r”
expect “assword:” {
send “$password\r”
expect “assword:”
send “$password\r”
send “\r”
send “exit\r”
expect eof
} “Unknown user” {
send “\r”
send “exit\r”
expect eof
}
if expect doesnt find the password, it will change to the unknown user statement and exit… you can treat the log later.

another suggestion would be to not allowing the webserver to have root and instead, save the command to a file and use chron to execute it later. this file can be outside the scope of webserver and you can block root change, etc.

Reply

60 Jason August 25, 2009 at 9:55 pm

Set this up and it works but the PHP does not change to say that it has completed???

Reply

61 Simon August 28, 2009 at 3:07 pm

Is there a way to get past the perceived risk of the script running as root ? i.e is there any way the script could be run as the connected user?

Reply

62 Corey August 28, 2009 at 8:02 pm

Has anyone thought about adding a secret question onto the php webpage? That way, you could use this script as a backend password change once the user has answered the secret question properly.

With such a system in place, the user can change there own password…. using presetup authentication.

any ideas?

Reply

63 Edson Michel December 29, 2009 at 8:39 pm

Thanks a lot
Your script help a lot but I have to do more configuration in linux for run it.
the aditional configuration is

use command chown in the script!!!
and watch the error_log of httpd

thanks again

Reply

64 tom January 13, 2010 at 11:52 am

Apache error_log says password

any help ?

Reply

65 Aurangzeb February 2, 2010 at 9:51 am

A unix sofrware is copied and installed on another hard drive but during booting it is protected, how to unprotect?

Reply

66 an0nym0us April 26, 2010 at 8:48 pm

Thank you.

One note for CentOS/RHEL users is that ‘requiretty’ is enabled by default in the sudoers file. To get around this add:

Defaults:www-data !requiretty

before the “www-data ALL=NOPASSWD: /var/www/chpasswd” line. Obviously you’ll need substitute the name of the user that the webserver runs under if it isn’t www-data (in CentOS it seems to be ‘apache’ by default).

Thanks again!

Reply

67 an0nym0us April 26, 2010 at 9:31 pm

@Terry

That’s a nice little function but it looks like it only works for users who have shell access. For instance, it looks like it won’t work for users with /sbin/nologin as a shell, such as is typical for FTP users.

Reply

68 Ashish May 27, 2010 at 1:23 pm

Hi;

Thanks for this script. It worked for me on Solaris 10.

regards;
Ashish

Reply

69 Akash July 11, 2010 at 3:36 pm

Hi; i m having problem with my php installation in linux on my pc. Whenever i try to start the service of php, it throws an error “service failed”. but it installs without any error if I connect my hard disk to someone else’s computer. can anyone has solution for this problem?????

Reply

70 Chris July 27, 2010 at 12:33 pm

The file in /tmp will contain the password briefly, allowing an attack vector. How about an interactive ssh shell through php?

[code]

Password Update Utility

Username

Current Password

New Password

Confirm New Password

<?php

if ($_POST['submitChangePassword'])
{
$error = "0";
# Die on root user
if ($_POST['username'] == 'root')
{
echo ('Authentication Failed');
}
else
{
# Connect and reset password
$connection = ssh2_connect($targetHost, $targetPort);

if (!ssh2_auth_password($connection, $_POST['username'], $_POST['OldPassword']))
{
echo ('Authentication Failed');
}
else
{
$out = '';
$last_line = '';
$cmds[0] = "passwd";
$cmds[1] = $_POST['OldPassword'];
$cmds[2] = $_POST['NewPassword'];
$cmds[3] = $_POST['NewPassword2'];
$shell = ssh2_shell($connection);

for($i=0; $i

[/code]

Reply

71 Rick November 13, 2010 at 2:46 am

Or you could just do the hash right in PHP using crypt, and then change the password in one command using perl:
usermod -p `perl -e ‘print crypt(\”password\”, \”user\”)’` user

Here’s an example of a PHP script to do it. This is part of a CGI I wrote. This is NOT how the actual CGI works. I stripped out the GET and PUT methods for clarity’s sake. Also, the real CGI doesn’t have root access. Instead, it communicates with another process that does. That combined with the fact that this script validates the current user and password makes it more secure.

Please do not grant CGI access to a script based on this example and place it on a Web site.

 "peter", "old" => "oldpassword", "new" => "newpassword");
    // Get the old password and new password
    $user = $data["user"];
    $old = $data["old"];
    $new = $data["new"];
	// Get the current password hash to compare
	// Read the file and return the data
	$old_hash = @file_get_contents($pw_path);
	if (!$old_hash)	// Couldn't access the file
    {
        printf("Cannot read password file: ".$pw_path."\n");
        return;
    }
    // Parse out the hash
    $old_hash = strstr($old_hash, $user);
	if (!$old_hash) // The user doesn't exist
    {
        printf("No user named ".$user." in ".$pw_path."\n");
        return;
	}
    // Get everything in front of the next ccarriage return
    $old_hash2 = strstr($old_hash, "\n", TRUE);
    // If it's the last line, that's ok too
    if (!$old_hash2)
        $old_hash2 = $old_hash;
    $old_hash = trim($old_hash2);
    // Could use explode, but this is just as easy
    $old_hash = strstr($old_hash, ":");
    $old_hash = substr($old_hash, 1);
    // PHP's crypt guesses the encryption alogrithm based on the "salt"
    // Linux passwords typically use MD5, so we'll just use the old hash.
    // Apache's htpasswd, for example, typically uses DES, so we would use
    // just the first to characters; $salt = substr($old_hash, 0, 2);
    $salt = $old_hash;
    // Now get a hash to match the existing password
    $new_hash = crypt($old, $salt);
    if ($new_hash != $old_hash)
    {
        printf("The entered password doesn't match the current password\n");
        return;
    }
    // Now change new passwords
	$command = sprintf($change_script, $new, $new, $new);
    $output = ExecuteCommand($command);
	// Now send the result
    printf($output."\n");
?>

Reply

72 Rick November 13, 2010 at 2:47 am

Sorry, that previous code listing was a bad cut and paste:

 "peter", "old" => "oldpassword", "new" => "newpassword");
    // Get the old password and new password
    $user = $data["user"];
    $old = $data["old"];
    $new = $data["new"];
	// Get the current password hash to compare
	// Read the file and return the data
	$old_hash = @file_get_contents($pw_path);
	if (!$old_hash)	// Couldn't access the file
    {
        printf("Cannot read password file: ".$pw_path."\n");
        return;
    }
    // Parse out the hash
    $old_hash = strstr($old_hash, $user);
	if (!$old_hash) // The user doesn't exist
    {
        printf("No user named ".$user." in ".$pw_path."\n");
        return;
	}
    // Get everything in front of the next ccarriage return
    $old_hash2 = strstr($old_hash, "\n", TRUE);
    // If it's the last line, that's ok too
    if (!$old_hash2)
        $old_hash2 = $old_hash;
    $old_hash = trim($old_hash2);
    // Could use explode, but this is just as easy
    $old_hash = strstr($old_hash, ":");
    $old_hash = substr($old_hash, 1);
    // PHP's crypt guesses the encryption alogrithm based on the "salt"
    // Linux passwords typically use MD5, so we'll just use the old hash.
    // Apache's htpasswd, for example, typically uses DES, so we would use
    // just the first to characters; $salt = substr($old_hash, 0, 2);
    $salt = $old_hash;
    // Now get a hash to match the existing password
    $new_hash = crypt($old, $salt);
    if ($new_hash != $old_hash)
    {
        printf("The entered password doesn't match the current password\n");
        return;
    }
    // Now change new passwords
	$command = sprintf($change_script, $new, $new, $new);
    $output = ExecuteCommand($command);
	// Now send the result
    printf($output."\n");
?>

Reply

73 Killzone 3 February 27, 2011 at 8:37 am

Hi I try run PHP login to my shell script and show results on wep page is work but my server must install PHP my admin

Reply

74 karthik June 6, 2011 at 12:13 pm

Hi
i am getting the below error when i tested the script in command line.
i have chmod 755 chpasswd.sh
error message …..
exec: 3: expect: not found
Kindly advice

Reply

Leave a Comment

Tagged as: , , , , ,

Previous post:

Next post: