Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Linux User password from PHP script

I have a "simple" question: How can I securely change a user's password from within a PHP script, without granting Apache root privileges or introducing other crazy security holes?

Background: CentOS 6, Apache 2.2.13, PHP 5.3.3

I am aware of the pam_chpasswd() command, which is part of the PECL PAM library. However, this function fails unless the host process (httpd) has read access to the /etc/shadow file. (BAD IDEA! Not sure how this library helps if it requires such high privileges...)

The ideal situation, as far as I can see, is to have PHP call a shell script with 'sudo -u[username of user changing his password]' This would run the script "AS" the user, so he should have permission to change his own password. And sudo would require that the user send along his existing password in order to be authenticated, thus preventing one user from changing another user's password.

But this doesn't work for some reason... when opening the process with popen, the process never executes. I have the shell script set up to dump some text into a publicly writable file in /tmp. But it never gets to that point.

$cmd = "/usr/bin/sudo -S -u$username /file_to_execute.sh";
$handle = popen ($cmd, "w");   // Open the process for writing
fwrite ($handle, "$current_password\n");  // Send the user's current password to sudo (-S option)
fwrite  .... (write the username, current password, and new password, so the script can change it)
$result = pclose($handle);

If I access this php script (http://server/script.php), the function immediately fails, and $result = 1

If I modify the sudoers file (visudo) and add a line:
$Defaults:apache !requiretty

The script freezes for about 10 seconds, then fails ($result = 1)

Any suggestions for doing this are greatly appreciated!

like image 684
Ryan Griggs Avatar asked Jul 24 '12 16:07

Ryan Griggs


1 Answers

To achieve the above with security in mind, I would suggest either the use of expect or adding the Apche user to a group who has write access to said file and only said file.

With expect, you will need to include your sudo password, as it will listen for the response from the OS of Password:, and when seen, it automatically replies with the sudo password. This would allow you to team up shell_exec() and family with expect to achieve your results.

I would go the second route for security, which would use a group permission to write to the file for a group which only has write access to that file.

Example:

groupadd secure_apache
usermod -G secure_apache apache_user
chown owner:secure_apache /tmp/file_to_change
chmod 740 /tmp/file_to_change
like image 81
Mike Mackintosh Avatar answered Sep 22 '22 14:09

Mike Mackintosh