一、使用 Directory Services(目录服务)的目的

对于局域网内的一个用户来讲,工作等其它应用需要,我们必须凭帐号登录主机、用帐号收发E-mail,甚至为了管理需要公司还需要维护一个电子号码簿来存储员工的姓名、地址、电话号码等信息。随着时间的增长,我们会为这些越来越多的帐号和密码弄的头晕脑胀。同时,如果一个员工离开,管理员就不得不翻遍所有的记录帐号信息的文件把离职员工的信息删除。这些将是一个繁琐而效率低下的工作。那么,如果能将此些帐号信息等统一到一个文件中进行管理,无疑会大大提高员工及管理员的工作效率。目录服务(LDAP是其实现的一种)正是基于这些应用实现的。

二、概述

LDAP:Lightweight Directory Access Protocol  轻量级目录访问协议

 

LDAP协议基于X.500标准, 与X.500不同,LDAP支持TCP/IP, 是跨平台的和标准的协议

 

LDIF(LDAP Interchange Format)是指存储LDAP配置信息及目录内容的标准文本文件格式,之所以使用文本文件来格式来存储这些信息是为了方便读取和修改,这也是其它大多数服务配置文件所采取的格式。

 

LDIF文件常用来向目录导入或更改记录信息,这些信息需要按照LDAP中schema的格式进行组织,并会接受schema 的检查,

如果不符合其要求的格式将会出现报错信息。LDIF文件样例如下:

dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org
objectClass:organizationalPerson
cn:stan
cn:czm
sn:czm

其中,以"#"号开头的为注释行;第二行起的行中,冒号左边为属性,右边是属性的值,这类同于编程中的变量及为其所赋的值,但属性可以被重复赋值。
注意:同一个属性可以有一个或者多个值,ldap在寻址时,可以根据同一个属性的不同值进行寻址,例如上例中可以根据cn属性的stan和czm进行寻址,这样速度更快。

 

(1)监听端口

TCP/IP port: 389
SSL port: 636

 

(2)objectClass 对象类由 LDAP 目录使用来定义给定类型的对象可以有哪些属性。对象类还定义项必须有什么属性,以及项可以有什么属性。所有对象类都从其父对象类继承需求,然后添加它们自己的需求。

 

(3)Attribute:Attribute类同于编程语言中的变量,它可以被赋值,就像是可以存放一个单一类型信息的容器。官方声明了许多常用的 Attribute,如果其中没有你所需要的,你可以自己定义,但要避免重名。objectClass是一种特殊的Attribute,它包含其它用到的 Attribute以及它自身。

 

(4)schema:LDAP中,schema用来指定一个目录中所包含的objects的类型(objectClass)以及每一个objectClass中的各个必备(mandatory)和可选(optional)的属性(attribute)。因此,Schema是一个数据模型,它被用来决定数据怎样被存储,被跟踪的数据的是什么类型,存储在不同的Entry下的数据之间的关系。schema 需要在主配置文件slapd.conf中指定,以用来决定本目录中使用到的objectClass。管理员可以自己设计制定schema,一般包括属性定义(AttributeDefinition)、类定义(ClassDefinition)以及语法定义(SyntaxDefinition)等部分。   

三、LDAP客户端和LDAP服务器端交互过程

1. 绑定。LDAP客户端与LDAP服务器建立连接。可匿名绑定,也可以用户名+密码形式绑定(具体参考LDAP Server, AD不支持匿名查询)。

2. LDAP客户端向LDAP服务器发出查询、添加、修改、删除entry等操作。  

3.解除绑定。LDAP客户端与LDAP服务器断开连接。

示例

linux客户机若要通过LDAP服务器作为身份认证,一般都是和PAM结合起来使用,因此需安装PAM及和LDAP相关的pam_ldap模块,而要成功配置PAM可不是件容易的。

 

1.tinylogin程序登录流程  
下面流程图是按照login程序中函数出现的顺序而成,都是C标准库里的函数.基本上可以看出login要处理的环节.

getty启动login进程
    ↓
+---------------------+
|  fflush  →  fgets  |     输入用户名.当登录认证失败时,login进程并不立即返回到getty,而是处理用户名输入. 
+---------------------+                当失败3次以上,login进程才退出并返回到getty   
    ↓                                 (说明:getty会先处理用户名输入过程,并将用户名传递给login进程)    
+---------------------+
|  getpwnam           |     获取用户信息.包括:用户名、用户密文、用户ID
+---------------------+
    ↓
+---------------------+
|  getpass            |     输入口令
+---------------------+
    ↓
+---------------------+
|  crypt              |     生成密文.将用户输入的口令生成密文
+---------------------+
    ↓
+---------------------+
|  strcmp             |     验证密文.将用户口令生成的密文与用户信息里的密文相比较
+---------------------+
    ↓
+----------------------------------------------+
|  initgroups → endgrent → setgid → setuid  |   切换用户ID.将正在运行的login进程的用户ID(为root身份)换为登录用户ID
+----------------------------------------------+
    ↓
+---------------------+
|  clearenv           |     清除环境变量.将当前的环境变量清除掉
+---------------------+
    ↓
+---------------------+
|  setenv             |     设置环境变量.有:TERM、HOME、SHELL、USER、LOGNAME、PATH
+---------------------+
    ↓
+---------------------+
|  execv              |     运行shell.如:bash、sh
+---------------------+
    ↓
login进程结束

2.pam_ldap程序验证流程

是基于LDAP的两次绑定验证,如下:

+------------------+          
| 登录名和密码录入 |
+------------------+                
    ↓ 
+--------------------------------+
| 第一次绑定(匿名或默认用户绑定) |  
+--------------------------------+
    ↓
+---------------------+        返回多个或0个entry 
| 根据登录名搜索entry |----------------------------->{登录名错误,结束} 
+---------------------+ 
    ↓返回唯一entry
+--------------------------+            绑定失败
| 第二次绑定(使用DN和密码) |---------------------> {密码错误,验证失败}
+--------------------------+
    ↓绑定成功
{验证成功}