提供正确密码仍出现PAM认证失败问题求助
PAM身份认证失败问题排查与解决
我尝试使用PAM进行身份认证,即便输入正确密码仍认证失败,仅返回“Authentication failed”的模糊错误信息。
问题代码
// gcc [file] -lstdc++ -lpam -lpam_misc #include <iostream> #include <security/pam_appl.h> #include <security/pam_misc.h> int main() { const char * username = "********"; const char * password = "********"; const char * data[] = {username, password}; struct pam_conv pconv = {misc_conv, data}; struct pam_handle *phandle = NULL; int result; result = pam_start("display_manager", username, &pconv, &phandle); std::cout << "pam_start: " << pam_strerror(phandle, result) << "\n"; result = pam_authenticate(phandle, 0); std::cout << "pam_authenticate: " << pam_strerror(phandle, result) << "\n"; }
系统日志(已脱敏)
Oct 08 19:50:26 ******** main[42928]: pam_warn(display_manager:auth): function=[pam_sm_authenticate] flags=0 service=[display_manager] terminal=[<unknown>] user=[********] ruser=[<unknown>] rhost=[<unknown>] Oct 08 19:50:26 ******** main[42928]: PAM pam_close_session: NULL pam handle passed Oct 08 19:50:26 ******** main[42928]: PAM pam_setcred: NULL pam handle passed Oct 08 19:50:26 ******** main[42928]: PAM pam_end: NULL pam handle passed
问题分析
- PAM服务配置缺失:日志中的
pam_warn(display_manager:auth)表明,PAM服务display_manager未配置实际认证模块,默认使用仅输出警告的pam_warn模块,无法完成真实认证。 - 资源未正确清理:日志中的
NULL pam handle passed是因为代码未调用pam_end清理会话资源,且未处理pam_start失败的情况,后续操作使用空句柄触发报错。
解决步骤
1. 配置PAM服务文件
在/etc/pam.d/目录下创建display_manager文件,添加系统密码认证规则:
auth required pam_unix.so account required pam_unix.so
设置文件权限为644,确保属主属组为root:
sudo chmod 644 /etc/pam.d/display_manager sudo chown root:root /etc/pam.d/display_manager
2. 完善代码的错误处理与资源清理
修改代码,添加pam_start失败判断,确保会话资源被正确释放:
// gcc [file] -lstdc++ -lpam -lpam_misc #include <iostream> #include <security/pam_appl.h> #include <security/pam_misc.h> int main() { const char * username = "********"; const char * password = "********"; const char * data[] = {username, password}; struct pam_conv pconv = {misc_conv, data}; struct pam_handle *phandle = NULL; int result; result = pam_start("display_manager", username, &pconv, &phandle); if (result != PAM_SUCCESS) { std::cout << "pam_start failed: " << pam_strerror(phandle, result) << "\n"; if (phandle != NULL) { pam_end(phandle, result); } return 1; } std::cout << "pam_start: " << pam_strerror(phandle, result) << "\n"; result = pam_authenticate(phandle, 0); std::cout << "pam_authenticate: " << pam_strerror(phandle, result) << "\n"; // 结束会话,释放资源 pam_end(phandle, result); return 0; }
3. 验证运行
重新编译并运行程序,输入正确密码时pam_authenticate应返回Success,认证成功。
内容的提问来源于stack exchange,提问作者WitHol
相关产品推荐
相关产品推荐

