• PAM从入门到精通(十九)


    接前一篇文章:PAM从入门到精通(十八)

    本文参考:

    《The Linux-PAM Application Developers' Guide》

    PAM 的应用开发和内部实现源码分析

     先再来重温一下PAM系统架构

    更加形象的形式:

    六、整体流程示例

    2. 更为完整的例程及解析

    上一回讲解了更为详细复杂例程的第二部分,本文继续讲解其余部分。再来贴一下完整代码:

    1. /* 使用PAM所必需的两个头文件*/
    2. #include
    3. #include
    4. static struct pam_conv conv = {
    5. misc_conv,
    6. NULL
    7. }
    8. void main(int argc, char *argv[], char **renvp)
    9. {
    10. pam_handle_t *pamh = NULL;
    11. int status;
    12. /* 初始化,并提供一个回调函数 */
    13. if ((pam_start("login", user_name, &conv, &pamh)) != PAM_SUCCESS)
    14. exit(1);
    15. /* 设置一些关于认证用户信息的参数 */
    16. pam_set_item(pamh, PAM_TTY, ttyn);
    17. pam_set_item(pamh, PAM_RHOST, remote_host);
    18. while (!authenticated && retry < MAX_RETRIES)
    19. {
    20. status = pam_authenticate(pamh, 0);/* 认证,检查用户输入的密码是否正确 */
    21. }
    22. /* 认证失败则应用程序退出*/
    23. if (status != PAM_SUCCESS)
    24. {
    25. ……
    26. exit(1);
    27. }
    28. /* 通过了密码认证之后再调用帐号管理API,检查用户帐号是否已经过期 */
    29. if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
    30. {
    31. if (status == PAM_AUTHTOK_EXPIRED)
    32. {
    33. status = pam_chauthtok(pamh, 0); /* 过期则要求用户更改密码 */
    34. if (status != PAM_SUCCESS)
    35. exit(1);
    36. }
    37. }
    38. /* 通过帐户管理检查之后则打开会话 */
    39. if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
    40. exit(status);
    41. ……
    42. /* 建立认证服务的用户证书*/
    43. status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
    44. if (status != PAM_SUCCESS)
    45. exit(status);
    46. ……
    47. pam_end(pamh, PAM_SUCCESS); /* PAM事务的结束 */
    48. ……
    49. }

    (6)pam_open_session函数

    代码片段:

    1. /* 通过帐户管理检查之后则打开会话 */
    2. if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
    3. exit(status);

    作用:

    启动PAM会话管理。pam_open_session函数为先前成功通过身份验证的用户设置用户会话。会话稍后应通过调用pam_close_session()来终止。

    应该注意的是,应用程序的有效uid(通过geteuid()获得)应该具有足够的权限来执行例如创建或挂载用户主目录之类的任务。

    参数详解:

    • pam_handle_t *pamh

    pamh参数是通过先前调用pam_start()获得的身份验证句柄。

    此处传给pamh的实参为main函数中定义的pam_handle_t *pamh的地址&pamh。

    • int flags

    flags参数是以下值中的零个或多个的二进制或:

    PAM_SILENT

    不发出任何消息。

    此处传给flags的实参为0。

    (7)pam_setcred函数

    代码片段:

    1. /* 建立认证服务的用户证书*/
    2. status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
    3. if (status != PAM_SUCCESS)
    4. exit(status);

    作用:

    设置用户凭证。pam_setcred函数用于建立、维护和删除用户的资格(凭据)。在对用户进行身份验证之后,在为用户打开会话之前(使用pam_open_session()),应该调用它来设置凭据。应在会话关闭后删除凭据(使用pam_close_session())。

    凭据(credential)是用户所拥有的东西。它是一些属性,如Kerberos票证或者构成给定用户的唯一性的补附加组成员资格。在Linux系统上,用户的UID和GID也是凭据。但是,已经决定这些属性(以及用户所属的默认补充组)是应由应用程序而不是PAM直接设置的凭据。应用程序应在调用此函数之前建立此类凭据。例如,initgroups()(或等效操作)应该(已)被执行。

    参数详解:

    • pam_handle_t *pamh

    pamh参数是通过先前调用pam_start()获得的身份验证句柄。

    此处传给pamh的实参为main函数中定义的pam_handle_t *pamh的地址&pamh。

    • int flags

    有效标志,其中任何一个可以与PAM_SILENT进行逻辑“或”运算,它们是:

    PAM_ESTABLISH_CRED

    初始化用户的凭据。

    PAM_DELETE_CRED

    删除用户的凭据。

    PAM_REINITIALIZE_CRED

    完全重新初始化用户凭据。

    PAM_REFRESH_CRED

    延长现有凭据的生命期(使用期限)。

    此处传给flags的实参为PAM_ESTABLISH_CRED。

    至此,代码流程中的所有函数就全部解析完了。

  • 相关阅读:
    多模态论文阅读-LLaVA
    postgresql-使用plpgsql批量插入用户测试数据
    Numpy(三)Numpy的函数与排序
    前端项目打包成docker镜像报错:Module not found: Can't resolve '@/app/components/admin/AdminApp'
    Ubuntu如何创建一个子用户并赋与管理员权限
    十二、【机器学习】【监督学习】- 岭回归 (Ridge Regression)
    测绘屠夫报表系统V1.0.0-beta
    uboot实践:从ext4根文件系统加载内核、设备树、ramdisk
    友善Nona Pi开发板ubuntu22.04系统用Python3.8.17的pip安装PyQt5.15.2时报错“Q_PID”这个宏未定义的一种解决办法
    GPU架构演进十年,从费米到安培
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/133977004