目录题外话.......................................................................................................................................2第一章PAM概念理解——体系结构......................................................................................31.1什么是PAM........................................................................................................................31.2PAM的分层体系结构........................................................................................................31.3功能实现层简介...............................................................................................................51.4应用接口层简介...............................................................................................................51.5配置文件简介...................................................................................................................71.6U盾的来源——口令映射................................................................................................9第二章PAMAPI解析............................................................................................................122.1PAM接口库主要数据结构..............................................................................................122.2PAMAPI几个重要的接口函数解析..............................................................................14第三章密码复杂度配置策略...............................................................................................163.1Linux用户密码策略......................................................................................................163.2cracklib模块................................................................................................................183.3配置文件修改示例.........................................................................................................20第四章PAM底层实现解析.....................................................................................................20题外话理解一个系统,本人认为应该从系统的目的和体系结构出发,先了解该系统的最终目的,其次了解系统的整体架构,最后带着目的和心中已经绘制好的架构图,逐步深入分析内部实现。本文主要对PAM体系结构、PAMAPI和PAM配置文件进行了一定程度的分析,同时简要的介绍了PAMSPI,意在使初学者能对PAM能有个整体和初步的了解,同时掌握初步的PAMAPI的使用能力。个别地方也许理解地不正确或者不全面,希望读者能够结合其他资料进行学习。第一章PAM概念理解——体系结构1.1什么是PAMPAM(PluggableAuthenticationModule),中文意思即可插拔的认证模块,按照本人的理解,简单的说就是一种用于认证的插件,这个插件可以对登陆的用户进行身份的鉴别,也可以对用户信息(账号、密码等)进行管理。它的优势就是,跟你要登陆的主程序无关,它就是一个只管负责身份鉴别的模块,以一个OA(办公自动化)系统举例,首先你要登录,那就进入OA系统的PAM模块,把你的账户和密码输给PAM模块,PAM模块要进行检查,检查成功了,才可以进入到OA系统操作主界面,当然如果你登陆不成功,那对不起,你连OA系统操作主界面的一面都没见过,直接从PAM模块退出了,相关活动图如图1.1所示。从图1.1中,可以看出,如果你的OA系统不需要进行用户的身份认证了,直接将图1.1PAM模块与OA系统关系图PAM模块去掉就可,如果你觉得你的PAM功能还不够强大,你那把它“拔”下来,再换个功能更强大的PAM也可,对OA系统没有任何影响。不过,如果你仅仅以为PAM里面只对账户和密码进行识别的话,那就太小瞧它的功能了,之后我会给大家一点一点的剥开PAM的神秘面纱,现在我们已经基本知道PAM是用来做什么的了,还是先来看看PAM的体系结构吧。1.2PAM的分层体系结构开始OA系统中的PAM模块OA系统主界面结束PAM为了实现其插件功能和易用性,它采取了分层设计思想:让各功能模块从应用程序中独立出来,然后通过PAMAPI作为两者联系的纽带,这样应用程序就可以根据需要灵活地在其中“插入”所需的功能模块,从而真正实现了“各类功能,随需而用”。这些功能模块,可分为这么几类(身份鉴别、帐户管理、会话管理以及口令管理)。实际上,这一思路非常符合软件设计中的高内聚,低耦合这一重要思想,PAM的体系如图1.2所示。图1.2PAM体系结构图从上图可以看出,PAMAPI起着承上启下的作用,它是应用程序和PAM功能模块之间联系的纽带:当应用程序调用PAMAPI时,应用接口层按照配置文件pam.conf的规定,加载相应的功能模块。然后把请求(即从应用程序那里得到的参数)传递给底层的功能模块,这时对应的功能模块就可以根据要求执行具体的操作了。当功能模块执行完相应操作后,将结果返回给应用接口层,然后由接口层根据配置的具体情况将来自功能模块的应答返回给应用程序。还拿OA系统举例,假定我们的OA系统不仅需要身份的鉴别,还需要账户的管理、口令的管理等功能,很简单,在我们的OA系统程序里只需要利用PAMAPI调用相关的接口函数即可,至于这些功能具体是怎么实现的,OA根本没必要知道。如图1.3,是OA系统与PAM插件的关系图。应用4应用2应用3应用1应用程序层功能实现层应用接口层配置文件PAMAPI身份鉴别账户管理会话管理口令管理提供提供调用调用图1.3OA系统与PAM插件关系图1.3功能实现层简介功能实现层处于整个结构的最底层,它向上为接口层提供用户身份鉴别等服务,也就是说所有具体的实现工作都是由该层的功能模块来完成的。对于应用程序,有些不但需要验证用户的口令,还可能要求验证用户的帐户是否已经过期。此外,有些应用程序也许还会要求记录当前会话的有关信息或改变口令等,所以PAM在功能实现层除了提供身份鉴别模块外,同时提供了帐户管理、会话管理以及口令管理功能的模块。当然,这四种功能模块并不是所有应用程序所必需的,而是根据需要灵活取舍。1.4应用接口层简介应用接口层位于PAM结构的中间部分,它向上为应用程序屏蔽了用户鉴别等过程的具体细节,向下调用功能实现层中的具体功能模块所提供的特定服务。由图1.2可以看出,它主要由PAMAPI和配置文件两部分组成,下面将逐一介绍。PAMAPI可以分为两类,一类是用于调用下层特定模块的接口,这类接口与底层的模块相对应,如表1-1所示。OA系统功能实现层应用接口层配置文件PAMAPI身份鉴别账户管理会话管理口令管理提供提供调用调用其他应用身份鉴别账户管理口令管理表1-1接口类型接口函数(API)函数功能认证管理pam_authenticate()认证用户pam_setcred()设置用户证书账号管理pam_acct_mgmt()帐号管理会话管理pam_open_session()打开会话pam_close_session()关闭会话口令管理pam_chauthtok()设置口令另一类接口通常并不与底层模块一一对应,它们的作用是对底层模块提供支持以及实现应用程序与模块之间的通信等。具体如下:1.管理性接口每组PAM事务从pam_start()开始,结束于pam_end()函数。接口pam_get_item()和pam_set_item()用来读写与PAM事务有关的状态信息。同时,能够用pam_str()输出PAM接口的出错信息。2.应用程序与功能模块间的通讯接口在应用程序初始化期间,某些诸如用户名之类的数据可以通过pam_start()将其存放在PAM接口层中,以备将来底层模块使用。另外,底层功能模块还可以使用pam_putenv()向应用程序传递特定的环境变量,然后应用程序利用pam_getenv()和pam_getenvlist()读取这些变量。3.用户与功能模块间的通讯接口pam_start()函数可以通过会话式的回调函数,让底层功能模块通过它们读写相关的信息,比如以应用程序所规定的方式提示用户输入口令。4.功能模块间通讯接口尽管各功能模块是独立的,但是他们仍然能够通过pam_get_item()和pam_set_item()接口共享某些公用信息,诸如用户名、服务名、口令等。此外,这些API还可以用于在调用pam_start()之后,让应用程序修改状态信息。5.读写模块状态信息的接口接口pam_get_data()和pam_set_data()用以按照PAM句柄要求访问和更新特定模块的信息。此外,还可以在这些模块后附加一个清除数据函数,以便当调用pam_end()时清除现场。由于PAM的功能模块随需加载,所以各功能模块初始化任务在第一次调用时完成。如果某些模块的清除任务必须在鉴别会话结束时完成,则它们应该使用pam_set_data()规定清除函数,这些执行清除任务的函数将在应用程序调用pam_end()接口时被调用。1.5配置文件简介我们注意到,配置文件也放在了在应用接口层中,它与PAMAPI配合使用,从而达到了在应用程序中灵活插入所需功能模块的目的。它的作用主要是为应用程序选定具体的功能模块、功能模块间的组合以及规定功能模块的行为。下面是一个示例配置文件:图1.4示例配置文件我们可以看到,配置文件有许多登记项(每行对应一个登记项)组成,每一行又分为五列(每列对应一栏),详细解释如下:第一栏,service表示使用PAM的应用程序,比如login、passwd、rlogin等。这一栏中的OTHER表示所有没在该文件中显式列出的应用。也就是说,如果所有程序具有相