![通过 Linux PAM 更改密码,无需以 root 身份运行应用程序](https://linux22.com/image/45473/%E9%80%9A%E8%BF%87%20Linux%20PAM%20%E6%9B%B4%E6%94%B9%E5%AF%86%E7%A0%81%EF%BC%8C%E6%97%A0%E9%9C%80%E4%BB%A5%20root%20%E8%BA%AB%E4%BB%BD%E8%BF%90%E8%A1%8C%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F.png)
我正在编写的应用程序将具有一些密码更改功能。但是我想知道是否可以不以 root 身份运行帐户管理部分。
现在我遇到了一个问题,如果我以我试图管理的用户身份运行,我将无法更改密码。我通过首先使用给定的密码进行身份验证来验证密码是否正确。 (单独调用身份验证模块的另一部分。)只有当我调用chauthtok
为用户更改它时pamtest
,它才会导致对话函数的调试输出:
START PAM CHANGE PASSWORD
PAM_CONV start [('Changing password for pamtest.', 4)]
PAM_CONV iter: Changing password for pamtest. 4
PAM_CONV end: [('', 0)]
PAM_CONV start [('(current) UNIX password: ', 1)]
PAM_CONV iter: (current) UNIX password: 1
PAM_CONV end: [(u'5ACN5pbmDFBVMHp', 0)]
PAM_CONV start [('Enter new UNIX password: ', 1)]
PAM_CONV iter: Enter new UNIX password: 1
PAM_CONV end: [(u'pdJb7ffsQTHWw4V', 0)]
PAM_CONV start [('Retype new UNIX password: ', 1)]
PAM_CONV iter: Retype new UNIX password: 1
PAM_CONV end: [(u'pdJb7ffsQTHWw4V', 0)]
Pass change failed for pamtest! '' (('Authentication token manipulation error', 20))
response:False
其中,调试标志pam_unix.so
在 rsyslogauth.log
文件中两次给出此行:
<date> <time> <system> python pam_unix(passwd:chauthtok): username [pamtest] obtained
这让我相信将更改后的密码写入影子文件存在问题。这可能是因为 root 是唯一具有写入权限的人。当我以 root 身份运行该代码时,该代码确实可以工作。
这是一个正确的假设吗?如果是,这通常是通过以 root 身份运行模块来完成的吗?或者是否有其他可用选项,例如创建仅具有写入影子文件权限的特定用户?
答案1
这让我相信将更改后的密码写入影子文件存在问题。这可能是因为 root 是唯一具有写入权限的人。当我以 root 身份运行该代码时,该代码确实可以工作。
这是一个正确的假设吗
是的。/etc/shadow
只能由 root 写入,因此您的程序只有在具有 root 权限时才能运行。
或者是否有其他可用选项,例如创建仅具有写入影子文件权限的特定用户?
编写一个“setuid root”程序。 setuid 意味着该程序始终具有 root 权限,无论哪个用户启动它。然后你的程序必须确保
- 呼叫用户只能更改自己的密码
- 呼叫用户已提供正确的旧密码
- 调用用户无法操纵您的程序来完全执行其他操作,例如启动 root shell
当然,编写 setuid 程序时必须非常小心。您的程序现在比调用用户拥有更多的权限,因此攻击者将尝试利用您的程序中的错误来将自己的权限提升为 root。
答案2
您可以使影子文件可由专用组(例如“shadow”)读取,并让您的应用程序对其运行 setgid。这至少可以确保,如果您的系统受到威胁,它只能读取用户数据库,而不能读取系统中的每个文件。但是,您的应用程序将无法更改进程的凭据,除非该进程是超级用户或当时附加了合适的功能并处于活动状态。