从PHP脚本修改Linux用户密码

时间:2022-09-02 02:19:49

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?

我有一个“简单”的问题:如何在PHP脚本中安全地更改用户密码,而不授予Apache root特权或引入其他疯狂的安全漏洞?

Background: CentOS 6, Apache 2.2.13, PHP 5.3.3

背景: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...)

我知道pam_chpasswd()命令,它是PECL PAM库的一部分。但是,除非主机进程(httpd)具有对/etc/shadow文件的读访问权限,否则此函数将失败。(坏主意!不确定这个库如何帮助如果它需要如此高的特权…

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.

在我看来,最理想的情况是让PHP调用一个shell脚本,该脚本带有“sudo -u”(用户更改密码的用户名),“这将运行脚本”作为“用户”,因此他应该拥有更改自己密码的权限。sudo将要求用户发送现有密码以进行身份验证,从而防止一个用户更改另一个用户的密码。

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.

但由于某种原因,这行不通……当使用popen打开进程时,该进程永远不会执行。我已经设置了shell脚本,将一些文本转储到/tmp中一个可公开写入的文件中。但它永远也达不到这一点。

$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

如果我访问这个php脚本(http://server/script.php),函数会立即失败,$result = 1。

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

如果我修改sudoers文件(visudo)并添加一行:$Defaults:apache !requiretty

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

脚本冻结大约10秒,然后失败($result = 1)

Any suggestions for doing this are greatly appreciated!

对于这样做的任何建议都非常感谢!

2 个解决方案

#1


2  

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.

为了实现上述的安全性,我建议使用expect,或者将Apche用户添加到具有对上述文件的写访问权限并只对所述文件进行写访问的组中。

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.

使用expect,您将需要包含您的sudo密码,因为它将侦听来自密码操作系统的响应:,并且当看到时,它将使用sudo密码自动回复。这将使您能够将shell_exec()和family组合在一起,期望实现您的结果。

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

#2


0  

A more secure way to do this is to store username and password in a file in a special directory and let cron do the job (once per minute)

一种更安全的方法是将用户名和密码存储在一个特殊目录的文件中,并让cron执行此操作(每分钟一次)

#1


2  

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.

为了实现上述的安全性,我建议使用expect,或者将Apche用户添加到具有对上述文件的写访问权限并只对所述文件进行写访问的组中。

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.

使用expect,您将需要包含您的sudo密码,因为它将侦听来自密码操作系统的响应:,并且当看到时,它将使用sudo密码自动回复。这将使您能够将shell_exec()和family组合在一起,期望实现您的结果。

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

#2


0  

A more secure way to do this is to store username and password in a file in a special directory and let cron do the job (once per minute)

一种更安全的方法是将用户名和密码存储在一个特殊目录的文件中,并让cron执行此操作(每分钟一次)