• PAM从入门到精通(四)


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

    本文参考:

    The Linux-PAM Application Developers' Guide

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

    更加形象的形式:

    五、主要函数详解

    1. pam_start

    概述:

    PAM事务初始化

    详细描述:

    pam_start函数创建PAM上下文并启动PAM事务。它是应用程序需要调用的第一个PAM函数。事务状态完全包含在此句柄标识的结构中,因此可以并行处理多个事务。但是不可能对不同的事务使用相同的句柄,每个新的上下文都需要一个新的句柄。

    函数声明:

    #include
    int pam_start ( service_name , user , pam_conversation , pamh );
    const char * service_name ;
    const char * user ;
    const struct pam_conv * pam_conversation ;
    pam_handle_t ** pamh ;

    参数说明:

    • const char *service_name

    service_name参数指定要应用的服务的名称,并将作为PAM_SEVICE项存储在新上下文中。服务的策略将从文件/etc/pam.d/service_name中读取,如果该文件不存在,则从/etc/pam.conf中读取。如:passwd(/etc/pam.d/passwd)、useradd(/etc/pam.d/useradd)等。

    • const char *user

    user参数可以指定目标用户的名称,并将存储为PAM_USER项。如果参数为NULL,则模块必须在必要时询问此项。

    • const struct pam_conv *pam_conversation

    pam_conversation参数指向描述要使用的会话函数的结构pam_conv。应用程序必须为加载的模块与应用程序之间的直接通信提供此功能。

    • pam_handle_t **pamh

    在成功返回(PAM_SUCCESS)之后,pamh的内容是一个句柄,它包含对PAM函数的连续调用的PAM上下文。在错误情况下,pamh的内容未定义。

    pam_handle_t是一个盲结构,应用程序不应试图直接探测其信息。而是应该通过PAM库提供的函数pam_set_item和pam_get_item。PAM句柄不能同时用于多个身份验证,只要以前没有对其调用pam_end函数。

    返回值:

    • PAM_ABORT:一般错误。
    • PAM_BUF_ERR:内存缓冲区错误。
    • PAM_SUCCESS:事务已成功创建。
    • PAM_SYSTEM_ERR:系统错误,例如提交了一个NULL指针而非指向数据的指针。

    实例:

    实例1. 一般性代码

    1. /* 初始化,并提供一个回调函数 */
    2. if ((pam_start("login", user_name, &pam_conv, &pamh)) != PAM_SUCCESS)
    3. exit(1);

    实例2. SDDM中的代码

    参见SDDM包源码目录src/helper/backend/PamHandle.cpp中的PamHandle::start函数。

    代码如下:

    1. bool PamHandle::start(const QString &service, const QString &user) {
    2. if (user.isEmpty())
    3. m_result = pam_start(qPrintable(service), NULL, &m_conv, &m_handle);
    4. else
    5. m_result = pam_start(qPrintable(service), qPrintable(user), &m_conv, &m_handle);
    6. if (m_result != PAM_SUCCESS) {
    7. qWarning() << "[PAM] start" << pam_strerror(m_handle, m_result);
    8. return false;
    9. }
    10. else {
    11. qDebug() << "[PAM] Starting...";
    12. }
    13. return true;
    14. }

    2. pam_end

    概述:

    PAM事务终止。

    详细描述:

    pam_end函数终止pam事务,是应用程序应在pam上下文中调用的最后一个函数。此函数为与pam_set_item和pam_get_item函数关联的项释放了所有内存。调用pam_end()后,与此类对象关联的指针不再有效。

    函数声明:

    #include

    int pam_end ( pamh , pam_status );
    pam_handle_t * pamh ;
    int pam_status ;

    参数说明:

    • pam_handle_t *pamh

    pamh参数是通过先前调用pam_start()获得的身份验证句柄。返回后,句柄pamh不再有效,并且与之相关的所有内存都将无效。

    • int pam_status

    pam_status参数应设置为上次PAM库调用返回给应用程序的值。

    pam_status获取的值用作模块特定回调函数cleanup的参数(参见pam_set_data()和pam_get_data())。通过这种方式,可以向模块发出拆除过程的通过/失败性质的通知,并在模块被取消链接之前执行适合模块的任何最后一分钟任务。

    此参数可以与PAM_DATA_SILENT进行逻辑“或”运算,以指示模块不应过于认真地对待调用。它通常用于指示库的当前关闭处于分支进程中,并且父进程将负责清理当前进程空间之外的内容(如文件等)。

    返回值:

    • PAM_SUCCESS:事务已成功创建。
    • PAM_SYSTEM_ERR:系统错误,例如一个NULL指针作为PAM句柄提交,或者函数被模块调用。

    实例:

    实例1. 一般性代码

        pam_end(pamh, PAM_SUCCESS);  /* PAM事务的结束 */

    实例2. SDDM中的代码

    参见SDDM包源码目录src/helper/backend/PamHandle.cpp中的PamHandle::end函数。

    代码如下:

    1. bool PamHandle::end(int flags) {
    2. if (!m_handle)
    3. return false;
    4. m_result = pam_end(m_handle, m_result | flags);
    5. if (m_result != PAM_SUCCESS) {
    6. qWarning() << "[PAM] end:" << pam_strerror(m_handle, m_result);
    7. return false;
    8. }
    9. else {
    10. qDebug() << "[PAM] Ended.";
    11. }
    12. m_handle = NULL;
    13. return true;
    14. }

    更多函数请看后续文章。

  • 相关阅读:
    【论文精度】Transformer--Attention Is All You Need
    一个优秀的软件测试工程师该如何进行需求分析
    day04-1群聊功能
    WSL VScode连接文件后无法修改(修改报错)
    .Net CLR GC动态获取函数头地址,C++的骚操作(慎入)
    晋江文学城PHP面试题(!带答案)
    linux进阶56——systemd实现程序日志保存成文件
    钉钉内嵌H5遇到的一些问题
    pybind11 连接C++11和Python
    python入门教程 3
  • 原文地址:https://blog.csdn.net/phmatthaus/article/details/133885558