在没有 PAM 的情况下验证用户身份的正确方法是什么?

在没有 PAM 的情况下验证用户身份的正确方法是什么?

由于我的相关问题似乎没有受到太多关注,这里还有另一个问题: 如今,在 Linux 中通过用户名/密码提示来验证用户身份的正确方法是什么?

原则上,我想我必须获取用户名和密码,从 中读取相应用户的盐和哈希值/etc/shadow。然后,我将计算给定密码和存储的盐的哈希值,并检查结果是否与存储在/etc/shadow.

通常,我可以简单地通过 PAM(例如pam_unix)进行身份验证,PAM 已经完成了所有这些操作,但我的应用程序是一个自定义 PAM 模块,并且我发现没有方法可以从另一个 PAM 模块调用一个 PAM 模块。如果这是可能的,我很乐意采用这个解决方案。

截至目前,我发现这个教程确实过时了http://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.html从 1996 年开始,显然,影子支持还没有内置到 libc 中。它提到pw_authvalid作为身份验证的辅助函数。我尝试将这些植入到我的代码中并链接到libshadow.a影子工具,但我收到pw_auth和 的“未解析的外部引用”错误valid。代码看起来像这样:

if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
     && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
    || !valid (passwd, pw)) {
    return (UPAP_AUTHNAK);
}

我没有进一步检查这一点,但无论如何这不是首选解决方案,因为每次更新 Shadow-utils 时我都必须更新我的代码。

我更愿意链接到一个提供针对/etc/shadow.有这样的东西吗,我还没找到?或者其他解决方案?

答案1

在我看来,你对 Shadow-utils 更新的恐惧是没有根据的。该 HOWTO 中描述的例程可以在我的 Ubuntu 12.04 和 Mint 17 系统上使用,无需安装任何特殊的东西。

/etc/shadow在 C 程序中读取信息的结构可以在/usr/include/shadow.h和 中找到man 5 shadow,并且您需要找到例如按名称定义的影子密码条目的函数,/usr/include/shadow.hgetspnam也会为您提供一个手册页 ( man getspnam) 描述该内容和所有相关功能。

基于此,您应该能够获取任何给定名称的哈希密码条目。哈希密码应该有多个“$”标记,从哈希密码中删除最后一个“$”之后的所有内容,包括最后一个“$”,并将其作为盐呈现给crypt(),glibc 版本(根据man 3 crypt)应该能够处理“扩展”盐表示当今更常见的 SHA512 条目。

相关内容