LINUX PAM验证机制

一.PAM简介
Linux-PAM(linux可插入认证模块)是一套共享库,使本地系统管理员可以随意选择程序的认证方式.
换句话说,不用(重新编写和)重新编译一个包含PAM功能的应用程序,就可以改变它使用的认证机制.
这种方式下,就算升级本地认证机制,也不用修改程序.
PAM使用配置文件/etc/pam.conf(或/etc/pam.d/下的文件),来管理对程序的认证方式.应用程序调用相应的配置文件,从而调用本地的认证模块.模块放置在/lib/security下,以加载动态库的形式进行调用(dlopen(3)).
像我们使用su命令时,系统会提示你输入root用户的密码.这就是su命令通过调用PAM模块实现的.
二. PAM的配置文件介绍
1.PAM配置文件的格式
PAM配置文件有两种写法: 一种是写在/etc/pam.conf中.格式如下:
ftpd auth required pam_unix.so nullok
ftpd:表示服务名,即针对哪一个服务进行的认证配置.
required:为模块类型.PAM有四中模块类型,分别代表不同的任务类型.
pam_unix.so:为模块路径.即要调用模块的位置.
nullok:为模块参数,即传递给模块的参数.
另一种写法是,将PAM配置文件放到/etc/pam.d/目录下,使用应用程序名作为配置文件名.如:
vsftpd,login等.配置文件的格式与pam.conf类似,只是少了最左边的服务名列.如:/etc/pam.d/cups
#%PAM-1.0
auth    required        pam_stack.so service=system-auth
account required        pam_stack.so service=system-auth
2.PAM的模块类型
Linux-PAM有四种模块类型,分别代表四种不同的任务.它们是:认证管理,账号管理,会话管理和密码管理.一个类型可能有多行,它们按顺序依次由PAM模块调用.
auth
用来对用户的身份进行识别.如:提示用户输入密码,或判断用户是否为root等.
account
对帐号的各项属性进行检查.如:是否允许登录,是否达到最大用户数,或是root用户是否允许在这个终端登录等.
session
这个模块用来定义用户登录前的,及用户退出后所要进行的操作.如:登录连接信息,用户数据的打开与关闭,挂载文件系统等.
password
使用用户信息来更新.如:修改用户密码.
3.PAM的控制标记
PAM使用控制标记来处理和判断各个模块的返回值.
required
这个标记表示需要模块返回一个成功值.如果返回失败,则继续进行同类型的下一个操作,当所有此类型的模块都执行完后.才返回失败值.
requisite
与required相似,但是如果这个模块返回失败,则立刻向应用程序返回失败,表示此类型失败.
不再进行同类型后面的操作.
sufficient
如果此模块返回成功,则直接向应用程序返回成功,表示此类型成功.不再进行同类型后面的操作.如果失败,也不会影响这个类型的返回值.
optional
使用这个标记的模块,将不进行成功与否的返回.一般返回一个PAM_IGNORE(忽略).
4.模块路径
模块路径.即要调用模块的位置. 一般保存在/lib/security/下,如: pam_unix.so同一个模块,可以出现在不同的类型中.它在不同的类型中所执行的操作都不相同.这是由于每个模块针对不同的模块类型,编制了不同的执行函数.
5.模块参数
模块参数,即传递给模块的参数.参数可以有多个,之间用空格分隔开,如:
password   required   pam_unix.so nullok obscure min=4 max=8 md5
三.编写PAM配置文件
1.PAM模块介绍
pam_unix.so模块:
auth类型: 提示用户输入密码,并与/etc/shadow文件相比对.匹配返回0(PAM_SUCCESS).
account类型: 检查用户的账号信息(包括是否过期等).帐号可用时,返回0.
password类型: 修改用户的密码. 将用户输入的密码,作为用户的新密码更新shadow文件pam_cracklib.so模块:
password类型: 这个模块可以插入到一个程序的密码栈中,用于检查密码的强度.
这个模块的动作是提示用户输入密码,并与系统中的字典进行比对,检查其强度.
pam_loginuid.so模块:
session类型:用来设置已通过认证的进程的uid.以使程序通过正常的审核(audit).
pam_securetty.so模块:
auth类型: 如果用户要以root登录时,则登录的tty必须在在/etc/securetty中法之前.
pam_rootok.so模块:
auth类型: pam_rootok模块用来认证用户id是否为0.为0返回”PAM_SUCCESS”.
pam_console.so模块:
session类型: 当用户登录到终端时,改变终端文件文件的权限.在用户登出后,再将它们修改回来.
pam_permit.so模块:
auth,account,password,session类型: pam_permit模块任何时候都返回成功.
pam_env.so模块 :
auth类型: pam_env允许设置环境变量.默认下,若没有指定文件,将依据/etc/security/pam_env.conf进行环境变量的设置.
pam_xauth.so模块:
session类型: pam_xauth用来在用户之间转发xauth-key.
如果不进行pam_xauth,当用户调用su成为另一个用户时,这个用户将不可以再访问原来用户的X显示,因为新用户没有访问显示的key.pam_xauth解决了当会话建立时,从原始用户到目标用户转发key和用户退出时销毁key的问题.
实验:
注销/etc/pam.d/su中的"session    optional     /lib/security/$ISA/pam_xauth.so"行在桌面终端执行su切换到另一个用户时,执行xterm会报错,提示无法访问DISPLAY.
删除注释后,再使用su切换到另一个用户时,执行xterm,会正常打开一个xterm终端窗口.
pam_stack.so模块:
auth,account,password,session: pam_stack可以调用另一个服务.也就是多个服务可以包含到一个设置中.当需要修改时,只修改一个文件就可以了.
pam_warn.so模块:
auth,account,password,session: pam_warn用来记录服务,终端,用户,远程用户和远程主机的信息到系统日志.模块总是返回PAM_IGNORE,意指不希望影响到认证处理.
2.编写PAM配置文件
以root身份执行: # vi /etc/pam.d/pamtest
#提示用户输入密码
auth     required   pam_unix.so
# 验证用户账号是否可用
account  required   pam_unix.so
# 向系统日志输出一条信息
account  required   pam_warn.so
四.基于PAM机制的应用程序
1.编写C源码
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <security/pam_modules.h>
#include <stdio.h>
/* 文件pamtest.c
此程序从命令行接收一个用户名作为参数,然后对这个用户名进行auth和account验证.
*/
// 定义一个pam_conv结构,用于与pam通信
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";
const char *s1=NULL;
if(argc == 2)
user = argv[1];
else
exit(1);
if(argc > 2) {
fprintf(stderr, "Usage: pamtest0 [username]\n");
exit(1);
}
printf("user: %s\n",user);
retval = 0;
//调用pamtest配置文件
retval = pam_start("pamtest", user, &conv, &pamh);
if (retval == PAM_SUCCESS)
//进行auth类型认证
retval = pam_authenticate(pamh, 0);    /* is user really user? */
else {
//如果认证出错,pam_strerror将输出错误信息.
printf("pam_authenticate(): %d\n",retval);
s1=pam_strerror( pamh, retval);
printf("%s\n",s1);
}
if (retval == PAM_SUCCESS)
//进行account类型认证
retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
else {
printf("pam_acct_mgmt() : %d\n",retval);
s1=pam_strerror( pamh, retval);
printf("%s\n",s1);
}
/* 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, "pamtest0: failed to release authenticator\n");
exit(1);
}
return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}
//END
2.编译
$ cc -o pamtest pamtest.c -lpam -lpam_misc -ldl
3.编写PAM配置文件
以root身份执行: vi /etc/pam.d/pamtest
auth  required  /lib/security/pam_unix.so
account required /lib/security/pam_unix.so
4. 修改可执行程序权限
由于pam_unix.so需要访问/etc/shadow和/etc/passwd文件,所以要给pamtest文件附上SUID权限.
# chown root.root pamtest
# chmod 111 pamtest
# ls pamtest
# ls pamtest -hl
---s--x--x 1 root root 12K 2007-07-16 01:52 pamtest
5.执行
pamtest程序通过pam_unix.so,先对用户的密码进行验证,然后对用户的账号信息进行验证.
以普通用户身份执行,输入错误的maj密码时.
maj@m2-u:01:52:09/var/tmp$ ./pamtest maj
user: maj
Password:
pam_acct_mgmt() : 7
Authentication failure
Not Authenticated
输入正确的密码时
maj@m2-u:01:54:44/var/tmp$ ./pamtest maj
user: maj
Password:
Authenticated
输入错误的root密码时
maj@m2-u:01:58:37/var/tmp$ ./pamtest root
user: root
Password:
pam_acct_mgmt() : 7
Authentication failure
Not Authenticated
maj@m2-u:01:59:15/var/tmp$
输入正确的root密码时
maj@m2-u:01:54:50/var/tmp$ ./pamtest root
user: root
Password:
Authenticated
maj@m2-u:01:58:37/var/tmp$

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

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

相关文章

java和node.js 2018_node.js在2018年能继续火起来吗?我们来看看node.js的待遇情况

你知道node.js是怎么火起来的吗&#xff1f;你知道node.js现在的平均工资是多少吗&#xff1f;你知道node.js在2018年还能继续火吗&#xff1f;都不知道&#xff1f;那就来看文章吧&#xff0c;多学点node.js&#xff0c;说不定以后的你工资就会高于nodejs的平均工资了&#xf…

hdu 2110 基础母函数

题意&#xff1a;退出本身并不麻烦&#xff0c;麻烦的是&#xff0c;退出的人需要取走相应比例&#xff08;1/3&#xff09;金额的资产。假设公司此时一共有n种价值的资产&#xff0c;每种价值的资产数量已知&#xff0c;请帮助心烦意乱的XHD夫妇计算一共有多少种分割资产的方法…

Python SIP使用总结(WinLinux通用)

From: http://topic.csdn.net/u/20120324/22/cd8796f8-c601-492c-992d-3d70d58ba51b.html?07033688857013248#replyachor 本文原先发表与我的博客。这是我做图像处理的时候摸索到的&#xff0c;现分享给大家。在用PythonOpenCV做影像分割、识别以及变换检测时&#xff0c;有…

java quartz 2.2.3_java – Spring 3 Quartz 2错误

当我用Quartz 2使用Spring 3时&#xff0c;我收到以下错误。有人知道原因吗&#xff1f;错误&#xff1a;Exception in thread "main" org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quart…

python中调用C++写的动态库

一、环境&#xff1a;Windows XP Python3.2 1. dll对应的源文件(m.cpp)&#xff1a; #include <stdio.h>extern "C" {_declspec(dllexport) int add(int a, int b){return ab;}_declspec(dllexport) void print_sum(unsigned long ulNum){while(ulNum ! 0){p…

Java注解入门

第一部分:了解一下java1.5起默认的三个annotation类型一个是Override:只能用在方法之上的&#xff0c;用来告诉别人这一个方法是改写父类的。 一个是Deprecated:建议别人不要使用旧的API的时候用的,编译的时候会产生警告信息,可以设定在程序里的所有的元素上. 一个是SuppressWa…

AspNetCms 国内×××聚

国内CMS&#xff1a; 1.SiteServer CMS SiteServer CMS 网站内容管理系统&#xff08;著作权登记号2008SR15710&#xff09;是定位于中高端市场的CMS内容管理系统&#xff0c;能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大的网站平台。…

java语言中的 继承_Java语言有关继承的总结

一、继承1、继承的概念继承机制是面向对向程序设计不可缺少的关键概念&#xff0c;是实现软件可重用的根基&#xff0c;是提高软件系统的可扩张性与可维护性的主要途径。(它允许创建分等级层次的类)。继承是指一个类的定义可以基于另一个已经存在的类&#xff0c;即子类基于父类…

[转]ssh常用用法小结

ssh常用用法小结 1、连接到远程主机&#xff1a; 命令格式 &#xff1a; ssh nameremoteserver 或者 ssh remoteserver -l name 说明&#xff1a;以上两种方式都可以远程登录到远程主机&#xff0c;server代表远程主机&#xff0c;name为登录远程主机的用户名。 2、连接到远程主…

正则基础之——反向引用

From: http://blog.csdn.net/lxcnn/article/details/4476746 1 概述 捕获组捕获到的内容&#xff0c;不仅可以在正则表达式外部通过程序进行引用&#xff0c;也可以在正则表达式内部进行引用&#xff0c;这种引用方式就是反向引用。要了解反向引用&#xff0c;首先要了…

Android教程之android平台水波效果!提供源码!

基于Android平台实现的水波效果&#xff0c;提供源码&#xff0c;&#xff0c;效果图如下&#xff1a;

java文件全是数字编码_批量将Java源代码文件的编码从GBK转为UTF-8

最近在做一个项目&#xff0c;需要从以前的另外一个项目迁移大量源代码过来&#xff0c;但是由于另一个项目采用GBK编码格式&#xff0c;而新项目采用的UTF-8编码格式&#xff0c;如果直接把Java源代码复制到Eclipse中所有的中文信息都出现乱码。将文本文件的编码格式从GBK转UT…

对于 IE低版本不兼容问题的处理

坑爹的IE低版本浏览器总是需要我们去编写特殊的代码才可以&#xff0c;脑残的我之前总是编写一套CSS&#xff0c;让页面在Firefox、Chorme等牛逼闪闪的浏览器与IE这SB浏览器中的显示差不多&#xff0c;差不多&#xff0c;谁懂么&#xff0c;好好的网页改得真是让人心塞&#xf…

vim中正则表达式匹配单词边界

一般的高级语言中匹配单词边界用的是"\b"&#xff0c;匹配非单词边界用"\B"。 但是在vim中使用\b&#xff0c;发现不认识。上网搜索了一番&#xff0c;终于找到了&#xff1a; 匹配单词左边界&#xff1a;\< 匹配单词右边界&#xff1a;\> 至于匹…

C++对象内存布局--④VS编译器--单个虚拟继承

C对象内存布局--④VS编译器--单个虚拟继承 在VS2005编译器下&#xff0c;证明单个虚拟继承的内存布局&#xff1a;无论有无虚函数&#xff0c;必然含有虚基类表指针。虚基类表中的内容为本类实例的偏移和基类实例的相对偏移值。 如果有虚函数&#xff0c;那么基类的虚函数表跟派…