• 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. }

    (2)pam_set_item函数

    代码片段:

    1. /* 设置一些关于认证用户信息的参数 */
    2. pam_set_item(pamh, PAM_TTY, ttyn);
    3. pam_set_item(pamh, PAM_RHOST, remote_host);

    作用:

    设置PAM项。pam_set_item函数允许应用程序和PAM服务模块访问和更新item_type的PAM信息。为此,将创建项参数指向的对象的副本。

    参数详解:

    • pam_handle_t *pamh

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

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

    • int item_type

    支持以下item_types:

    •         PAM_SERVICE

    服务名称(标识PAM函数将用于验证程序的PAM堆栈)。

    •         PAM_USER

    将使用其提供身份服务的实体的用户名。也就是说,在身份验证之后,PAM_USER标识可以使用该服务的本地实体。

    注意,PAM堆栈中的任何模块都可以将该值从某个事物(例如,“匿名”)映射到其它事物(例如“guest119”)。

    •         PAM_USER_PROMPT

    提示输入用户名时使用的字符串。此字符串的默认值是“login:”的本地化版本。

    •         PAM_TTY

    终端名称:如果是设备文件,则前缀为/dev/;对于图形化的、基于X的应用程序,该项的值应该是$DISPLAY变量。

    •         PAM_RUSER

    请求用户名:本地请求用户的本地名称或远程请求用户的远程用户名。

    通常,应用程序或模块会尝试提供经过最强身份验证的值(在远程帐户之前是本地帐户)。该值的信任级别体现在与应用程序相关联的实际身份验证堆栈中,因此最终由系统管理员决定。

    PAM_RUSER@PAM_RHOST应始终识别请求用户。在某些情况下,PAM_RUSER可能为NULL。在此种情况下,不清楚提出请求的实体是谁。

    •         PAM_RHOST

    请求主机名(PAM_RUSER实体请求服务的机器的主机名)。这就是PAM_RUSER@PAM_RHOST确实标识了请求用户。在某些应用程序中,PAM_RHOST可能为NULL。在这种情况下,不清楚身份验证请求的来源。

    •         PAM_AUTHOK

    身份验证令牌(通常是密码)。除了pam_sm_authenticate()和pam_sm_chauthtok()之外,所有模块函数都应该忽略此令牌。在前一个函数中,它用于将最新的身份验证令牌从一个堆叠的模块传递到另一个模块。在后一个函数中,令牌用于另一个目的。它包含当前活动的身份验证令牌。

    •         PAM_OLDAUTHOK

    旧的身份验证令牌。除pam_sm_chauthtok()外,所有模块函数都应忽略此令牌。

    •         PAM_CONV

    pam_conv结构。参见pam_conv。

    以下附加项目是特定于Linux PAM的,不应在可移植应用程序中使用:

    •         PAM_FAIL_DELAY

    用于重定向集中管理的故障延迟的函数指针。参见pam_fail_delay。

    •         PAM_XDISPLAY

    X display的名称。对于图形化的、基于X的应用程序,该项的值应该是$DISPLAY变量。该值可以独立于PAM_TTY用于传递display的名称。

    •         PAM_XAUTHDATA

    指向一个结构的指针,该结构包含连接到PAM_XDISPLAY指定的显示器所需的X身份验证数据(如果需要此类信息)。参见pam_xauth_data。

    •         PAM_AUTHOK_TYPE

    默认操作是模块在请求密码时使用以下提示:“New UNIX password:”和“Retype UNIX password:”。示例单词UNIX可以替换为此项,默认情况下为空。此项目由pam_get_authtok使用。

    此处传给item_type的实参分别为PAM_TTY和PAM_RHOST,分别表示请求终端名称和请求主机名。

    • const void *item

    对于除PAM_CONV和PAM_FAIL_DELAY之外的所有item_type,item都是指向以为结束符的字符串的指针。在PAM_CONV的情况下,item指向初始化的PAM_CONV结构。在PAM_FAIL_DELAY的情况下,item是函数指针:void(*DELAY_fn)(int retval,unsigned usec_DELAY,void*appdata_ptr)。

    PAM_AUTHTOK和PAM_OLDAUTHTOK都将在返回应用程序之前重新设定种子。这意味着应用程序无法访问身份验证令牌。

    此处传给item的实参分别为ttyn和remote_host,分别表示请求终端名称和请求主机名。

    更多讲解请看下回。

  • 相关阅读:
    基于ATMega328微控制器的APRS Kiss TNC: 从原理到C语言实现的完整指南
    重学Elasticsearch第2章 : ElasticSearch客户端操作索引、映射、文档
    一些基础提(选择题)
    SpringBoot-28-springSecurity注销和权限控制
    《c++程序设计》谭浩强课后习题答案 第二章
    编程在生活中的小应用
    快速LLaMA:面向大型语言模型的查询感知推理加速 论文摘要翻译与评论
    MySQL——连接查询与子查询
    数据结构之队列
    基于JavaSwing开发推箱子小游戏(音乐背景) 课程设计 大作业 毕业设计
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/133957164