为 OSX 编写可插拔身份验证模块 (PAM)

h_b*_*h_b 5 authentication macos pam dylib

我正在尝试获得一个基本的 PAM,以便在 OSX 上使用屏幕保护程序身份验证。代码很简单,只要对一切都返回true即可(类似于pam_permit)。我希望当用户想要从屏幕保护程序返回到他们的帐户时,无论他们输入什么密码,pam_sm_authenticate 都会返回 true。但是,这并不能正常工作,从屏幕保护程序返回仍然需要正确的用户密码。我究竟做错了什么。具体来说:

/usr/lib/pam 中的所有库都是 .so,但我用 Xcode 构建的库是 .bundle 或 .dylib。我是否需要采取任何额外的步骤来让 PAM 加载这些?(这里是 OSX 菜鸟)。

代码:

#define PAM_SM_ACCOUNT
#define PAM_SM_AUTH
#define PAM_SM_PASSWORD
#define PAM_SM_SESSION

#include <security/pam_appl.h>
#include <security/pam_modules.h>

PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) {
return(PAM_SUCCESS);
}

PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)           {
    return(PAM_SUCCESS);
}

PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return(PAM_SUCCESS);
}

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return(PAM_SUCCESS);
}

PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return(PAM_SUCCESS);
}

PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    return(PAM_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)

我尝试将上述内容构建到 Xcode 中的共享库中,输出为 OSXLoginBundle.bundle(或 .dylib),并将此包/dylib 复制到 /usr/lib/pam。我已将 /etc/pam.d 中的屏幕保护程序配置文件更改为

# screensaver: auth account
auth       sufficient     OSXLoginBundle.bundle
account    required       pam_opendirectory.so
account    sufficient     pam_self.so
account    required       pam_group.so no_warn group=admin,wheel fail_safe
account    required       pam_group.so no_warn deny group=admin,wheel ruser fail_safe
Run Code Online (Sandbox Code Playgroud)

The*_*ght 3

我假设您的代码正在被处理并且您已经检查过,并且我认为您误解了 pam 的工作原理。

参考pam.conf 文件(是的,我知道这里没有,但我相信这仍然适用于 pam.d 文件)

虽然同一服务和设施的行出现的顺序很重要,但列出各个服务和设施的顺序并不重要。

如果您阅读有关pam-policies 的内容,它会指出有 4 个模块链,每个模块链对应一个设施(身份验证、帐户、会话、密码)。

pam-policies 文档指出:-

当应用程序调用 pam_start(3) 时,PAM 库加载指定服务的策略并构建四个模块链(每个设施一个。)

由于调用 pam 的应用程序可以访问6 个身份验证函数(原语),这些函数根据 4 个设施分组,因此当应用程序(本例中为屏幕保护程序)调用不在“auth”设施下的原语时,它将不匹配你的 pam 模块,而是相关链中的模块。

因此,当调用应用程序调用pam_acct_mgmt时,它将引用 /etc/pam.d 中的屏幕保护程序文件并匹配关联的设施,在本例中为“帐户”,其中一些模块被标记为“必需”。

如果您要将其策略更改为“可选”,根据“链和策略”文档,这些模块的结果将被忽略。