PAM从入门到精通(十六)

news2024/11/9 10:04:42

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

 本文参考:

《The Linux-PAM Application Developers' Guide》

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

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

更加形象的形式:

六、整体流程示例

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

上一回讲解了《The Linux-PAM Application Developers' Guide》的“Chapter 8. An example application ”中给出的一个示例代码。官方文档中的例程太过简单了,只调用了4个应用接口函数,并且也没有更进一步的处理。下边再给出一个更为详细复杂的例程,其涵盖了大多数PAM应用接口函数(实际上就是前边各文章中“实例1. 一般性代码”的串联所组成的整体流程)。

代码如下:

/* 使用PAM所必需的两个头文件*/
#include <security/pam_appl.h>
#include <security/pam_misc.h>

static struct pam_conv conv = {
    misc_conv,
    NULL
}

void main(int argc, char *argv[], char **renvp)
{
    pam_handle_t *pamh = NULL;
    int status;

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

    /* 设置一些关于认证用户信息的参数 */
    pam_set_item(pamh, PAM_TTY, ttyn);
    pam_set_item(pamh, PAM_RHOST, remote_host);
    while (!authenticated && retry < MAX_RETRIES)
    {
        status = pam_authenticate(pamh, 0);/* 认证,检查用户输入的密码是否正确 */
    }
    /* 认证失败则应用程序退出*/
    if (status != PAM_SUCCESS)
    {
      	……
        exit(1);
    }

    /*  通过了密码认证之后再调用帐号管理API,检查用户帐号是否已经过期 */
    if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
    {
        if (status == PAM_AUTHTOK_EXPIRED)
        {
            status = pam_chauthtok(pamh, 0);  /* 过期则要求用户更改密码 */
            if (status != PAM_SUCCESS)
                exit(1);
        }
    }
    /* 通过帐户管理检查之后则打开会话 */
    if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
        exit(status);
	……
    /* 建立认证服务的用户证书*/
    status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
    if (status != PAM_SUCCESS)
       exit(status);
   	……
    pam_end(pamh, PAM_SUCCESS);  /* PAM事务的结束 */
    ……
 }

再来详解一下这个更为全面的流程步骤:

(1)pam_start函数

代码片段:

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

作用:

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

参数详解:

  • 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)等。

此处传给service_name的实参为"login",服务的策略将从文件/etc/pam.d/login中读取。该文件内容如下:

$ ls /etc/pam.d/login 
/etc/pam.d/login

$ cat /etc/pam.d/login 
# Begin /etc/pam.d/login

# Set failure delay before next prompt to 3 seconds
auth      optional    pam_faildelay.so  delay=3000000

# Check to make sure that the user is allowed to login
auth      requisite   pam_nologin.so

# Check to make sure that root is allowed to login
# Disabled by default. You will need to create /etc/securetty
# file for this module to function. See man 5 securetty.
#auth      required    pam_securetty.so

# Additional group memberships - disabled by default
#auth      optional    pam_group.so

# include system auth settings
auth      include     system-auth

# check access for the user
account   required    pam_access.so

# include system account settings
account   include     system-account

# Set default environment variables for the user
session   required    pam_env.so

# Set resource limits for the user
session   required    pam_limits.so

# Display date of last login - Disabled by default
#session   optional    pam_lastlog.so

# Display the message of the day - Disabled by default
#session   optional    pam_motd.so

# Check user's mail - Disabled by default
#session   optional    pam_mail.so      standard quiet

# include system session and password settings
session   include     system-session
password  include     system-password

# End /etc/pam.d/login
  • const char *user

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

此处传给user的实参为用户通过命令行或图形界面输入的用户名。

  • const struct pam_conv *pam_conversation

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

此处传给pam_conversation的实参为&conv。

  • pam_handle_t **path

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

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

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

(8)pam_start函数

代码片段:

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

作用:

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

参数详解:

  • pam_handle_t *pamh

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

此处传给pamh的实参为上边调用pam_start()的时候得到的那个pamh。

  • int pam_status

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

pam_status获取的值用作模块特定回调函数cleanup的参数。通过这种方式,可以向模块发出拆除过程的通过/失败性质的通知,并在模块被取消链接之前执行适合模块的任何最后一分钟任务。此参数可以与PAM_DATA_SILENT进行逻辑“或”运算,以指示模块不应过于认真地对待调用。它通常用于指示库的当前关闭处于分支进程中,并且父进程将负责清理当前进程空间之外的内容(如文件等)。

此处传给pam_status的实参为PAM_SUCCESS。

更多讲解请看下回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK3568笔记三:基于ResNet18的Cifar-10分类识别训练部署

若该文为原创文章&#xff0c;转载请注明原文出处。 本篇文章参考的是野火-lubancat的rk3568教程&#xff0c;本篇记录了在正点原子的ATK-DLK3568部署。 一、介绍 ResNet18 是一种卷积神经网络&#xff0c;它有 18 层深度&#xff0c;其中包括带有权重的卷积层和全连接层。它…

Mysql架构解析,InnoDB架构概述。

MySQL架构解析 Mysql整体架构 MySQL整体架构如下图所示&#xff1a; MySQL逻辑系统架构分为4层: 应用层MySQL服务层存储引擎层系统文件层 下面将对各层的功能和组件进行介绍&#xff0c;并探讨一条语句的执行过程。 应用层 应用层是MySQL体系架构的最上层&#xff0c;它…

Docker——【部署项目的最优解】使用DockerCompose部署项目

目录 前言 1、安装docker-compose 2、为什么使用docker-compose&#xff1f; 3、如何使用DockerCompose 3.1、创建docker-compose文件 3.2、docker-compose相关命令&#xff1a; 前言 对Docker常规操作部署项目不了解的伙伴&#xff0c;可以先看看这篇文章&#xff1a;h…

多商户进驻小程序商城的作用是什么

多商户进驻商城简单来说就是在一个商城里&#xff0c;由经营者邀请同行、异业商家进驻到商城里&#xff08;子商户&#xff09;&#xff0c;可丰富商城经营业态&#xff0c;满足客户多方购物需求&#xff0c;打造购物商圈及经营者获得更多收益等。 通过【雨科】平台的多商户进驻…

Anaconda安装第三方库

一定要使用国内镜像源来进行下载&#xff0c;否则会非常慢&#xff01; 有兴趣的可以看看下面的文章^~^ 新版PyCharm安装第三方库更换国内下载镜像地址 OK!安装完成&#xff01;

Oracle数据中如何在 where in() 条件传参

一、问题场景描述 在sql 条件中&#xff0c;如何在 where in()中想传入参数&#xff0c;如果直接 where in(:seqList)&#xff0c;当传入单个值&#xff0c;seqList: ‘80’ 是没问题的&#xff0c;但是初入多个值时&#xff0c;seqList: ‘80,90’ &#xff0c;因缺少单引号&…

Windows重启开机在不登录系统情况下自启指定程序

问题前言&#xff1a; 项目开发完成后需要部署上线&#xff0c;首次肯定是手动部署跑项目&#xff0c;后期如果出现断电或其他原因导致服务器关机需要重启服务器的情况&#xff0c;这个时候再远程过去手动跑项目是很鸡肋的&#xff0c;通常会设置程序开机自启动&#xff0c;这…

eNSP-OSPF协议其他区域不与骨干区域相连解决方法3

virtual-link技术 AR1 [ar1]int g0/0/0 [ar1-GigabitEthernet0/0/0]ip add 192.168.1.1 24 [ar1-GigabitEthernet0/0/0]quit [ar1]ospf [ar1-ospf-1]area 0 [ar1-ospf-1-area-0.0.0.0]net 192.168.1.0 0.0.0.255 [ar1-ospf-1-area-0.0.0.0]quit AR2 [ar2]int g0/0/0 [ar2-Gig…

C语言的输入输出和条件判断

目录 数据类型、运算符与表达式 1.数据类型 基本数据类型包括 取值范围 2.常量和变量 常量 变量 定义变量 变量的分类 为什么要用变量 3.输入与输出 格式输出函数printf&#xff08;&#xff09; 打印时的输出类型 格式输入函数scanf&#xff08;&#xff09; 4…

C++设计模式_10_ Prototype 原型模式(小模式,不太常用)

Prototype 原型模式仍然属于“对象创建模式”模式的一种。前面两篇介绍的工厂方法模式和抽象工厂模式的流行程度要远大于Prototype 原型模式和builder构建器模式&#xff0c;后两种由于较为简单&#xff0c;介绍篇幅也会少一些。 文章目录 1. 动机 (Motivation)2. 代码演示Prot…

解决方案 | 法大大电子签助力融资租赁突围数字化

融资租赁作为我国非银金融市场的重要组成部分&#xff0c;具有融资和融物两方面功能&#xff0c;不仅能够拓宽市场主体的融资渠道&#xff0c;而且也是促进先进制造业、战略性新兴产业、绿色产业等领域高质量发展的重要助力。 2023年以来&#xff0c;多地相继出台了一系列鼓励…

众和策略:股票中总量和现量是什么意思?

股票商场是出资者最常用的一种出资办法之一&#xff0c;股票的价格动摇与供需联系有很大的联系。而供需联系中&#xff0c;总量和现量被广泛关注&#xff0c;它们别离指的是某一时期内的股票发行总量和现有交易量。在本文中&#xff0c;咱们将从多个角度分析股票中总量和现量的…

[每周一更]-(第68期):Excel常用函数及常用操作

日常工作&#xff0c;偶尔也会存在excel表格入库的情况&#xff0c;针对复杂的入库情况&#xff0c;一般都是代码编号&#xff0c;读文件-写db形式&#xff1b;但是有些简单就直接操作&#xff0c;但是 这些简单的入库不仅仅是直接入库&#xff0c;而是内容中有部分需要进行映射…

接口测试(jmeter和postman 接口使用)

接口测试基础知识 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。把前端&#xff08;client&#xff09;和后端&#xff08;server&#xff09;联系起来&#xff0c;测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系…

Keeplived安装部署(单机双机)

Keeplived官网&#xff1a;https://www.keepalived.org/download.html 一 单机安装配置: 1.上传keepalived安装包并且安装 [rootmaster1 local]# tar -zxvf keepalived-2.2.8.tar.gz [rootmaster1 local]# mv keepalived-2.2.8 keepalived [rootmaster1 local]# chown root:r…

docker安装es分词插件ik详情步骤

1.下载ik查询 根据es版本去下载对应的版本&#xff0c;游览器中输入下面下载链接 https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.7.1/elasticsearch-analysis-ik-8.7.1.zip 2.2.若有对应版本跳过&#xff0c;若没有对应版本&#xff08;比如我需…

将语义分割的标注mask转为目标检测的bbox

1. 语义分割标签 1.1 labelme工具 语义分割的标签是利用labelme工具进行标注的,标注的样式如下: 1.2 语义分割的标签样式 2. 转换语义分割的标注到目标检测的bbox 实现步骤 (1) 利用标注的json文件生成mask图片(2) 在mask图片中找到目标的bbox矩形框的左上角点和右下角点(…

TCP通信-使用线程池优化

下面的通信架构存在问题&#xff1a; 客户端与服务端的线程模型是&#xff1a; N-N的关系&#xff0c;客户端并发越多&#xff0c;系统瘫痪的越快。 引入线程池处理多个客户端消息 代码实现 public class ClientDemo1 {public static void main(String[] args) {try {Syste…

C++是不是最容易产生猪队友的编程语言之一?

C是不是最容易产生猪队友的编程语言之一&#xff1f; 猪队友不是什么编程语言产生的&#xff0c;而是其做派本身就是猪队友&#xff0c;比如说自己一知半解的东西用得飞 起&#xff0c;而且不愿意深层次去学;再比如说不愿意写单元测试&#xff0c;甚至普通的测试都懒得做。最近…

在chrom浏览器安装Vue.js devtools插件,遇到恶意扩展程序字样,附百度网盘下载链接

遇到的问题 拖拽下载好的 Vue.js devtools 插件到谷歌扩展程序&#xff0c; 百度网盘下载地址 链接&#xff1a;https://pan.baidu.com/s/1FeK6pwc2UzRUUlMFN3rW5w?pwdw361 提取码&#xff1a;w361 提示&#xff1a; 解决办法 将Vue.js devtools 插件的后缀从.crx改为.zi…