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()后,与此类对象关联的指针不再有效。

相关推荐
ManageEngine卓豪8 个月前
如何监控特权帐户,保护敏感数据
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安全
蓝天居士1 年前
PAM从入门到精通(七)
pam·linux安全