为何PAM API的pam_get_data()报错且pam_set_data后数据无法获取
PAM认证函数重复调用导致数据获取失败的问题排查
我最近碰到了个PAM相关的头疼问题——一次SSH登录会话里,PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)居然被调用了两次!这个函数本身需要向外部服务器发请求,所以我第一次调用时用pam_set_data把会话数据存在了pamh句柄里,结果第二次调用时用pam_get_data根本拿不到之前存的数据,还报了"No module specific data is present"的未初始化错误。
相关代码片段如下:
#define _GNU_SOURCE #include "pam_hook.h" /* 标准C头文件及定义 */ /* 其他PAM相关代码内容 */
可能的原因和排查思路:
- 先确认PAM上下文是否一致:在
pam_sm_authenticate里打印pamh的指针地址,如果两次调用的地址不一样,说明是两个完全独立的PAM上下文——这种情况很常见,比如SSH会发起两次认证流程(比如先试密码、再试键盘交互),此时两次调用的pamh是不同实例,之前存的数据自然无法共享。 - 检查
pam_set_data的返回值:你有没有验证过pam_set_data是否返回了PAM_SUCCESS?如果调用失败,数据根本没被存入pamh,后续pam_get_data肯定拿不到结果。 - 确保数据键的唯一性:
pam_set_data的第二个参数是数据的标识键,这个键必须全局唯一,避免和其他PAM模块的键冲突。建议用你的模块名作为前缀,比如"my_custom_pam_session_data"。 - 考虑跨上下文的数据共享方案:如果确实需要在两次独立的认证调用间共享数据,
pam_set_data就不太够用了——可以考虑用外部存储(比如临时文件、共享内存),但要注意加锁处理并发问题;或者如果你的PAM模块支持会话初始化,可以在pam_sm_open_session里存储全局会话数据。 - 检查SSHD的PAM配置:看看
/etc/pam.d/sshd里的配置,是不是同一个认证模块被重复调用,或者配置了多种验证方式,导致触发了两次pam_sm_authenticate调用。
内容的提问来源于stack exchange,提问作者Omer Anisfeld
相关产品推荐
相关产品推荐

