PAM从入门到精通(十五)

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

本文参考:

《The Linux-PAM Application Developers' Guide》

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

更加形象的形式:

六、整体流程示例

1. 官方文档中的例程及解析

PAM从入门到精通(四)起到上一回止,整体结合实例讲解了《The Linux-PAM Application Developers' Guide》中的"Chapter 3. The public interface toLinux-PAM"中的3.1,实际上对应了上图中的PAM-API部分。不过看了各函数之后,对于总体流程还是缺少了了解和把握。本回就以一个示例(代码)将之前这些函数串起来,以对于总体流程以及各函数之间的顺序和关系有更好的理解。

示例代码参见《The Linux-PAM Application Developers' Guide》的"Chapter 8. An example application "。

为了了解Linux PAM应用程序的编写方式,我们包括以下示例。它会提示用户输入密码,并在标准输出中指示他们的帐户是否有效,其返回代码也指示成功与否(0表示成功;1表示失败)。

代码如下:

cpp 复制代码
/*
  This program was contributed by Shane Watts
  [modifications by AGM and kukuk]
  You need to add the following (or equivalent) to the
  /etc/pam.d/check_user file:
  # check authorization
  auth required pam_unix.so
  account required pam_unix.so
 */
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>

static struct pam_conv conv = {
    misc_conv,
    NULL
}

int main(int argc, char *argv[])
{
    pam_handle_t *pamh=NULL;
    int retval;
    const char *user="nobody";

    if(argc == 2) {
        user = argv[1];
    }
    if(argc > 2) {
        fprintf(stderr, "Usage: check_user [username]\n");
        exit(1);
    }

    retval = pam_start("check_user", user, &conv, &pamh);

    if (retval == PAM_SUCCESS)
        retval = pam_authenticate(pamh, 0); /* is user really user? */

    if (retval == PAM_SUCCESS)
        retval = pam_acct_mgmt(pamh, 0); /* permitted access? */

    /* This is where we have been authorized or not. */
    if (retval == PAM_SUCCESS) {
        fprintf(stdout, "Authenticated\n");
    } else {
        fprintf(stdout, "Not Authenticated\n");
    }
 
    if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
        pamh = NULL;
        fprintf(stderr, "check_user: failed to release authenticator\n");
        exit(1);
    }

    return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */
}

说实话,这代码写得很一般,argc为1时的情况没有考虑进来。不过不必关注这些细枝末节,人家把主要的流程讲清楚了。整个流程分为以下步骤:

(1)pam_start函数

代码片段:

cpp 复制代码
    retval = pam_start("check_user", user, &conv, &pamh);

作用:

PAM事务初始化。

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

(2)pam_authenticate函数

代码片段:

cpp 复制代码
    retval = pam_authenticate(pamh, 0); /* is user really user? */

作用:

对用户进行身份认证。

pam_authenticate函数用于对用户进行身份验证。用户被要求提供一个基于身份验证服务的身份验证令牌,通常这是一个密码,但也可能是指纹。

PAM服务模块可以请求用户通过对话机制输入其用户名(参见pam_start()和pam_conv())。经过身份验证的用户名称将出现在PAM的PAM_USER项中。可以通过调用pam_get_item()来恢复此项目。

(3)pam_acct_mgmt函数

代码片段:

cpp 复制代码
    retval = pam_acct_mgmt(pamh, 0); /* permitted access? */

作用:

账户验证管理。

pam_acct_mgmt函数用于确定用户的帐户是否有效。它检查身份验证令牌和帐户过期与否,并验证访问限制。其通常在用户经过身份验证后调用。

(4)pam_end

代码片段:

cpp 复制代码
    if (pam_end(pamh,retval) != PAM_SUCCESS) { /* close Linux-PAM */
        pamh = NULL;
        fprintf(stderr, "check_user: failed to release authenticator\n");
        exit(1);
    }

作用:

终止PAM事务。

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

相关推荐
派拉软件7 天前
2025金融新规施行!AI+PAM打造智能合规知识库
人工智能·金融·pam·金融合规知识库
ManageEngine卓豪1 年前
如何监控特权帐户,保护敏感数据
pam·敏感数据保护·特权账户监控
ManageEngine卓豪1 年前
适用于 Linux 和 Unix 的特权访问管理
linux·unix·pam·特权访问管理
岬淢箫声1 年前
如何通过PAM禁止部分用户登录
linux·ubuntu·centos·ssh·pam·sssd
ManageEngine卓豪1 年前
零信任特权访问管理
零信任·pam·特权访问·特权访问管理
蓝天居士1 年前
PAM从入门到精通(十九)
pam·linux安全
蓝天居士1 年前
PAM从入门到精通(十六)
pam·linux安全
蓝天居士1 年前
PAM从入门到精通(十二)
pam·linux安全
蓝天居士1 年前
PAM从入门到精通(十)
pam·linux安全