LDAP協(xié)議
目錄是一組具有類似屬性、以一定邏輯和層次組合的信息。常見的例子是通訊簿,由以字母順序排列的名字、地址和電話號(hào)碼組成。
目錄服務(wù)是一種在分布式環(huán)境中發(fā)現(xiàn)目標(biāo)的方法。目錄具有兩個(gè)主要組成部分:
第一部分是數(shù)據(jù)庫,數(shù)據(jù)庫是分布式的,且擁有一個(gè)描述數(shù)據(jù)的規(guī)劃。
第二部分則是訪問和處理數(shù)據(jù)的各種協(xié)議。
目錄服務(wù)其實(shí)也是一種數(shù)據(jù)庫系統(tǒng),只是這種數(shù)據(jù)庫是一種樹形結(jié)構(gòu),而不是通常使用的關(guān)系數(shù)據(jù)庫。目錄服務(wù)與關(guān)系數(shù)據(jù)庫之間的主要區(qū)別在于:二者都允許對存儲(chǔ)數(shù)據(jù)進(jìn)行訪問,只是目錄主要用于讀取,其查詢的效率很高,而關(guān)系數(shù)據(jù)庫則是為讀寫而設(shè)計(jì)的。
提示:目錄服務(wù)不適于進(jìn)行頻繁的更新,屬于典型的分布式結(jié)構(gòu)。
LDAP是一個(gè)目錄服務(wù)協(xié)議,目前存在眾多版本的LDAP,而最常見的則是V2和V3兩個(gè)版本,它們分別于1995年和1997年首次發(fā)布。
LDAP的基本模型
LDAP的基本模型是建立在“條目”(Entry)的基礎(chǔ)上。一個(gè)條目是一個(gè)或多個(gè)屬性的集合,并且具有一個(gè)全局唯一的“可區(qū)分名稱”(用dn表示)。與關(guān)系型數(shù)據(jù)(后面簡稱數(shù)據(jù)庫)進(jìn)行類比,一個(gè)條目相當(dāng)于數(shù)據(jù)庫中的一條記錄,而dn相當(dāng)于數(shù)據(jù)庫中記錄的關(guān)鍵字,屬性相當(dāng)于數(shù)據(jù)庫中的字段。
提示:dn必須是全局唯一的。
LDAP中,將數(shù)據(jù)組織成一個(gè)樹形結(jié)構(gòu),這與現(xiàn)實(shí)生活中的很多數(shù)據(jù)結(jié)構(gòu)可以對應(yīng)起來,而不像設(shè)計(jì)關(guān)系型數(shù)據(jù)庫的表,需要進(jìn)行多種變化。例如,圖1-1所示就是一個(gè)樹形結(jié)構(gòu)的數(shù)據(jù)。
在圖1-1所示的樹形結(jié)構(gòu)中,樹的根結(jié)點(diǎn)是一個(gè)組織的域名(dlw.com),其下分為3個(gè)部分,分別是managers、people和group,可將這3個(gè)組看作組織中的3個(gè)部門,如managers用來管理所有管理人員,people用來管理登錄系統(tǒng)的用戶,group用來管理系統(tǒng)中的用戶組。當(dāng)然,在該圖中還可繼續(xù)增加其他分支。
對于圖1-1所示的樹形結(jié)構(gòu),使用關(guān)系數(shù)據(jù)庫來保存數(shù)據(jù)的話,需要設(shè)置多個(gè)表,一層一層分別保存,當(dāng)需要查找某個(gè)信息時(shí),再逐層進(jìn)行查詢,最終得到結(jié)果。
若使用目錄來保存該圖中的數(shù)據(jù),則更直觀。圖中每個(gè)結(jié)點(diǎn)用一個(gè)條目來保存,不同類型的結(jié)點(diǎn)需要保存的數(shù)據(jù)可能不同,在LDAP中通過一個(gè)稱為objectClass的類型來控制不同結(jié)點(diǎn)需要的數(shù)據(jù)(稱為屬性)。
對于目錄中的數(shù)據(jù)怎樣進(jìn)行引用呢?前面提到過,每一個(gè)條目都有一個(gè)dn,因?yàn)閐n是唯一的,因此就可找到需要結(jié)點(diǎn)的數(shù)據(jù)。dn的構(gòu)造方式如下:
首先得到條目自己的名稱(rdn,稱為相對dn),然后開始向上逐級查找父結(jié)點(diǎn),一直到根項(xiàng)為止。例如,對于圖1-1中最右下方的結(jié)點(diǎn),其dn為:
Python代碼
dn: cn=ldap, ou=group, o=dlw.com
通過這樣的方式,即可唯一標(biāo)識(shí)每一個(gè)結(jié)點(diǎn)。
在現(xiàn)實(shí)生活中,有很多這種樹形結(jié)構(gòu)的數(shù)據(jù),如計(jì)算機(jī)文件系統(tǒng)的目錄結(jié)構(gòu)、Internet中的域名等。這些類型的數(shù)據(jù),只要不需要頻繁的更新,都適合用目錄來保存。
LDAP的功能
在LDAP的功能模型中定義了一系列利用LDAP協(xié)議的操作,主要包含以下4部分:
查詢操作:允許查詢目錄和取得數(shù)據(jù),其查詢性能比關(guān)系數(shù)據(jù)庫好。
更新操作:目錄的更新操作沒關(guān)系數(shù)據(jù)庫方便,更新性能較差,但也同樣允許進(jìn)行添加、刪除、修改等操作。
復(fù)制操作:前面也提到過,LDAP是一種典型的分布式結(jié)構(gòu),提供復(fù)制操作,可將主服務(wù)器的數(shù)據(jù)的更新復(fù)制到設(shè)置的從服務(wù)器中。
認(rèn)證和管理操作:允許客戶端在目錄中識(shí)別自己,并且能夠控制一個(gè)會(huì)話的性質(zhì)。
LDAP協(xié)議的特點(diǎn)
LDAP是一種目錄服務(wù),保存在特殊的數(shù)據(jù)庫中,數(shù)據(jù)的讀取速度遠(yuǎn)高于寫入速度。
LDAP對查詢做了優(yōu)化,讀取速度優(yōu)于普通關(guān)系數(shù)據(jù)庫。
LDAP不支持事務(wù)、不能進(jìn)行回滾,需要進(jìn)行這些操作的應(yīng)用只有選擇關(guān)系數(shù)據(jù)庫。
LDAP采用服務(wù)器/客戶端模式,支持分布式結(jié)構(gòu)。
LDAP中的條目以樹形結(jié)構(gòu)組織和存儲(chǔ)。
LDAP基于Internet協(xié)議,直接運(yùn)行在簡單和通用的TCP/IP或其他可靠的傳輸協(xié)議層上,使連接的建立和包的處理簡單、快捷,對于互聯(lián)網(wǎng)和企業(yè)網(wǎng)應(yīng)用都很方便。
LDAP協(xié)議簡單,通過使用查找操作實(shí)現(xiàn)列表操作和讀操作。
LDAP通過引用機(jī)制實(shí)現(xiàn)分布式訪問,通過客戶端API實(shí)現(xiàn)分布式操作(對于應(yīng)用透明),平衡了負(fù)載。
LDAP實(shí)現(xiàn)具有低費(fèi)用、易配置和易管理的特點(diǎn),并提供了滿足應(yīng)用程序?qū)δ夸浄?wù)所需求的特性。
安裝OpenLDAP
在RHEL 5的安裝光盤中提供了OpenLDAP 2.3.27軟件包,通過OpenLDAP軟件可實(shí)現(xiàn)LDAP服務(wù)。OpenLDAP程序包括客戶端、服務(wù)器、開發(fā)工具包等軟件包,本節(jié)將介紹安裝這些程序包的具體過程。
可以先通過rpm命令查詢系統(tǒng)中是否已安裝OpenLDAP服務(wù)器程序,若未安裝該服務(wù)器程序,再使用rpm命令從RHEL光盤中安裝該程序。
從RHEL 5安裝光盤中找到OpenLDAP服務(wù)器程序,并安裝到當(dāng)前系統(tǒng)中。
具體操作步驟如下:
(1)在進(jìn)行安裝以前,首先使用以下命令創(chuàng)建管理OpenLDAP的用戶和組。
Python代碼
# groupadd ldap
# useradd -g ldap ldap
# passwd ldap
(2)執(zhí)行以下命令,查詢系統(tǒng)中是否已安裝openldap-servers程序。
Python代碼
# rpm -qa openldap-servers
若無任何輸出,則表示當(dāng)前系統(tǒng)中未安裝openldap-servers服務(wù)器程序。
(3)使用以下命令將RHEL安裝光盤掛載到系統(tǒng)中:
Python代碼
# mount /dev/cdrom /mnt/cdrom
(4)執(zhí)行以下命令安裝openldap-servers程序的依賴程序包libtools-ltdl:
Python代碼
# rpm -ivh /mnt/cdrom/Server/libtool-ltdl-1.5.22-6.1.i386.rpm
若不執(zhí)行上面的命令,直接執(zhí)行下一步的安裝命令,將提示有依賴程序未安裝。
(5)執(zhí)行以下命令安裝openldap-servers程序:
Python代碼
# rpm -ivh /mnt/cdrom/Server/openldap-servers-2.3.27-5.i386.rpm
這樣就將openldap-servers服務(wù)器程序安裝到系統(tǒng)中了。整個(gè)安裝過程如下圖所示。
(6)使用以下命令修改保存數(shù)據(jù)的目錄/var/lib/ldap/及其文件的所有者,并修改權(quán)限,只有l(wèi)dap用戶才對數(shù)據(jù)有讀寫權(quán)限:
Python代碼
# chown ldap.ldap /var/lib/ldap
# chmod -R 600 /var/lib/ldap
在光盤中還有以下與openldap有關(guān)的軟件包,也可使用類似命令進(jìn)行安裝,這里不再逐個(gè)介紹。
● openldap-clients-2.3.27-5.i386.rpm:客戶端操作的相關(guān)程序。
● openldap-devel-2.3.27-5.i386.rpm:開發(fā)包。
測試安裝正確性
安裝完成后,將在/var/lib/目錄中創(chuàng)建一個(gè)子目錄ldap來保存數(shù)據(jù),同時(shí)在/etc/目錄中也將創(chuàng)建一個(gè)子目錄openldap來保存配置文件。而openldap的守護(hù)進(jìn)程slapd則保存在/usr/bin/目錄中。
提示:如果是通過源代碼進(jìn)行編譯安裝的openldap,這些程序文件放置的位置可能不同。
1.啟動(dòng)服務(wù)進(jìn)程
要檢查安裝是否正確,可直接運(yùn)行守護(hù)進(jìn)程,這里將使用默認(rèn)的配置。
啟動(dòng)OpenLDAP服務(wù)器可使用以下命令之一:
Python代碼
# server ldap start
# /etc/rc.d/init.d/ldap
# /usr/sbin/slapd
使用第1條命令來啟動(dòng)ldap服務(wù)進(jìn)程的過程如下圖所示。
提示:使用/usr/sbin/slapd命令啟動(dòng)服務(wù)程序是最好的一種方式,如果用前兩條命令啟動(dòng)openldap服務(wù)程序失敗,可使用最后一條命令試一下。
從上圖可看出,啟動(dòng)的是slapd進(jìn)程,并有一個(gè)提示信息,提示沒有DB_CONFIG文件。可通過以下命令將DB_CONFIG文件復(fù)制到/var/lib/ldap/目錄中:
Python代碼
# cp /etc/openldap/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
另外,由于使用的是默認(rèn)配置文件,提示希望使用后綴“dc=my-domain, dc=com”。下節(jié)將介紹修改配置文件的操作。
2.查看監(jiān)聽端口
OpenLDAP使用的監(jiān)聽端口是389,通過netstat命令查看該端口是否處于監(jiān)聽狀態(tài),可了解slapd進(jìn)程是否在工作。具體命令如下:
Python代碼
# netstat –tnlp | grep 389
執(zhí)行結(jié)果如下圖所示,可以看出,389端口處于監(jiān)聽狀態(tài),表示slapd進(jìn)程正在工作。
3.搜索測試
slapd服務(wù)進(jìn)程啟動(dòng)后,可使用OpenLDAP客戶端的一個(gè)搜索命令進(jìn)行一次搜索,以檢查服務(wù)的配置是否正確。
使用以下命令進(jìn)行搜索:
Python代碼
# ldapsearch -x -b '' -s base '(objectclass=*)'
注意:-b后面是兩個(gè)單引號(hào),用來阻止特殊字符被Shell解析。
由于還未向LDAP服務(wù)器中添加任何數(shù)據(jù),因此,系統(tǒng)中應(yīng)該只有“根”這個(gè)條目,執(zhí)行以上搜索的結(jié)果如下圖所示。
從以上測試可看出,OpenLDAP已經(jīng)正確安裝到系統(tǒng)中,接下來就需要修改配置文件,設(shè)置LDAP的根目錄了。
配置OpenLDAP
在上面的例子中的搜索結(jié)果可看出,在配置文件中是以默認(rèn)的“dc=my-domain, dc=com”作為后綴,需要對其進(jìn)行修改,當(dāng)然也還需要修改其他的一些配置。下面將介紹對配置文件的修改操作。
slapd.conf
OpenLDAP的配置文件位于/etc/openldap/目錄中,名稱為slapd.conf。該文件內(nèi)容較多,通常只需要修改幾個(gè)地方即可,包括修改后綴、管理員及其密碼。其初始內(nèi)容如下:
Python代碼
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=my-domain,dc=com"
rootdn "cn=Manager,dc=my-domain,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
# rootpw secret
# rootpw {crypt}ijFYNcSNctBYg
其中各語句的含義如下:
● 以符號(hào)“#”開始的行是注釋行,第1~3行、第8~12行都是。
● 第5行設(shè)置數(shù)據(jù)庫,可使用ldbm或bdb。
● 第6行設(shè)置后綴。
● 第7行設(shè)置超級管理員的名稱,與Linux系統(tǒng)中的root類似。在配置時(shí)用該用戶,配置完成后,建議將其刪除。
● 第11行設(shè)置超級管理員的密碼,默認(rèn)狀態(tài)是被注釋了的。這行的密碼是明文狀態(tài)。
● 第12行也是設(shè)置超級管理員的密碼,這行是以加密方式設(shè)置的(默認(rèn)狀態(tài)也是被注釋了的)。
根據(jù)實(shí)際情況,修改第6、7、11行即可,具體如下:
Python代碼
#######################################################################
# ldbm and/or bdb database definitions
#######################################################################
database bdb
suffix "dc=dlw,dc=com"
rootdn "cn=root,dc=dlw,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret
# rootpw {crypt}ijFYNcSNctBYg
以上內(nèi)容中,第6行將后綴修改為“dc=dlw,dc=com”,同時(shí)第7行的超級管理員的后綴部分也需要隨之修改。將第11行的注釋取消,設(shè)置超級管理員的密碼為MD5密碼secret。
修改密碼時(shí)需要注意rootpw前面不要有空格,以及rootpw與密碼之間使用Tab鍵分割。
經(jīng)過以上修改,保存后退出,接著使用以下命令重啟slapd進(jìn)程:
Python代碼
# service ldap restart
了解schema
對于LDAP目錄中保存的信息,可以使用LDIF(LDAP Interchange Format)格式來保存。這是一種標(biāo)準(zhǔn)文本文件格式,使用這種格式保存得的LDAP服務(wù)器數(shù)據(jù)庫中的數(shù)據(jù)可方便讀取和修改,這也是其他大多數(shù)服務(wù)配置文件所采取的格式。
LDIF文件常用來向目錄導(dǎo)入或更改記錄信息,這些信息需要按照LDAP中schema的格式進(jìn)行組織,并會(huì)接受schema的檢查,不符合其要求的格式將會(huì)出現(xiàn)報(bào)錯(cuò)信息。有關(guān)LDIF文件的格式和創(chuàng)建將在第4章進(jìn)行介紹,這里簡單介紹一下組織LDAP數(shù)據(jù)格式的schema文件。
在LDAP中,schema用來指定一個(gè)目錄中所包含的對象(objects)的類型(objectClass),以及每一個(gè)類型(objectClass)中必須提供的屬性(Atrribute)和可選的屬性??蓪chema理解為面向?qū)ο蟪绦蛟O(shè)計(jì)中的類,通過類定義一個(gè)具體的對象。LDIF中的數(shù)據(jù)條目可理解為是一個(gè)具體的對象,是通過schema來規(guī)劃創(chuàng)建的。因此,schema是一個(gè)數(shù)據(jù)模型,用來決定數(shù)據(jù)按什么方式存儲(chǔ),并定義存儲(chǔ)在不同的條目(Entry)下的數(shù)據(jù)之間的關(guān)系。schema需要在主配置文件slapd.conf中指定,以用來決定在目錄中可以使用哪些objectClass。
在/etc/openldap/schema/目錄中提供了許多schema文件,只需要在配置文件slapd.conf中使用include命令將需要使用的schema包含即可。例如,配置文件默認(rèn)包含了以下schema文件:
寫道
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
提示:通常使用系統(tǒng)提供的schema就可解決大部分應(yīng)用。管理員也可以自己設(shè)計(jì)制定schema,一般包括屬性定義(AttributeDefinition)、類定義(ClassDefinition)以及語法定義(SyntaxDefinition)等部分。這里就不介紹具體的設(shè)計(jì)方法了。
管理OpenLDAP
啟動(dòng)OpenLDAP服務(wù)器程序之后,接下來的操作就是通過客戶端程序?qū)δ夸涍M(jìn)行操作,包括添加、修改、刪除和搜索數(shù)據(jù)等操作。能對LDAP進(jìn)行操作的客戶端程序很多,下面簡單介紹在Linux命令方式下進(jìn)行這些操作的方法。
向目錄數(shù)據(jù)庫中添加數(shù)據(jù)
初始狀態(tài)下,LDAP是一個(gè)空目錄,即沒有任何數(shù)據(jù)??赏ㄟ^程序代碼向目錄數(shù)據(jù)庫中添加數(shù)據(jù),也可使用OpenLDAP客戶端工具ldapadd命令來完成添加數(shù)據(jù)的操作,該命令可將一個(gè)LDIF文件中的條目添加到目錄。因此,需要首先創(chuàng)建一個(gè)LDIF文件,然后再進(jìn)行添加操作。
1.LDIF文本條目格式
LDIF用文本格式表示目錄數(shù)據(jù)庫的信息,以方便用戶創(chuàng)建、閱讀和修改。在LDIF文件中,一個(gè)條目的基本格式如下:
寫道
# 注釋
dn: 條目名
屬性描述: 值
屬性描述: 值
屬性描述: 值
... ...
dn行類似于關(guān)系數(shù)據(jù)庫中一條記錄的關(guān)鍵字,不能與其他dn重復(fù)。一個(gè)LDIF文件中可以包含多個(gè)條目,每個(gè)條目之間用一個(gè)空行分隔。
例如,以下內(nèi)容組成一個(gè)條目:
寫道
1: dn: dc=dlw, dc=com
2: objectclass: top
3: objectclass: dcobject
4: objectclass: organization
5: dc: dlw
6: o: dlw,Inc.
在以上文本中,各行含義如下:
第1行的dn定義該條目的標(biāo)識(shí)。
第2~4行定義該條目的objectcCass,可以定義多個(gè)屬性,如上面代碼中定義了3個(gè)objectClass。條目的屬性根據(jù)objectClass的不同而不同,有的objectClass有必須設(shè)置的屬性。在2~4行的3個(gè)objectClass中,top沒有必須定義的屬性,dcobject必須定義屬性dc,用來表示一個(gè)域名的部分,而organization必須定義屬性o,用來表示一個(gè)組織的名稱。
根據(jù)objectClass的要求,第5、6行分別定義屬性dc和屬性o的值。
2.了解objectClass
LDAP中,一個(gè)條目必須包含一個(gè)objectClass屬性,且需要賦予至少一個(gè)值。每一個(gè)值將用作一條LDAP條目進(jìn)行數(shù)據(jù)存儲(chǔ)的模板;模板中包含了一個(gè)條目必須被賦值的屬性和可選的屬性。
objectClass有著嚴(yán)格的等級之分,最頂層是top和alias。例如,organizationalPerson這個(gè)objectClass就隸屬于person,而person又隸屬于top。
objectClass可分為以下3類:
結(jié)構(gòu)型(Structural):如person和organizationUnit;
輔助型(Auxiliary):如extensibeObject;
抽象型(Abstract):如top,抽象型的objectClass不能直接使用。
在OpenLDAP的schema中定義了很多objectClass,下面列出部分常用的objectClass的名稱。
● account
● alias
● dcobject
● domain
● ipHost
● organization
● organizationalRole
● organizationalUnit
● person
● organizationalPerson
● inetOrgPerson
● residentialPerson
● posixAccount
● posixGroup
3.了解Attribute
屬性(Attribute)類似于程序設(shè)計(jì)中的變量,可以被賦值。在OpenLDAP中聲明了許多常用的Attribute(用戶也可自己定義Attribute)。常見的Attribute含義如下:
● c:國家。
● cn:common name,指一個(gè)對象的名字。如果指人,需要使用其全名。
● dc:domain Component,常用來指一個(gè)域名的一部分。
● givenName:指一個(gè)人的名字,不能用來指姓。
● l:指一個(gè)地名,如一個(gè)城市或者其他地理區(qū)域的名字。
● mail:電子信箱地址。
● o:organizationName,指一個(gè)組織的名字。
● ou:organizationalUnitName,指一個(gè)組織單元的名字。
● sn:surname,指一個(gè)人的姓。
● telephoneNumber:電話號(hào)碼,應(yīng)該帶有所在的國家的代碼。
● uid:userid,通常指某個(gè)用戶的登錄名,與Linux系統(tǒng)中用戶的uid不同。
提示:objectClass是一種特殊的Attribute,它包含其他用到的Attribute以及其自身。
對于不同的objectClass,通常具有一些必設(shè)屬性值和一些可選屬性值。例如,可使用person這個(gè)objectClass來表示系統(tǒng)中一個(gè)用戶的條目,對于系統(tǒng)中用戶通常需要有這樣一些信息:姓名、電話、密碼、描述等。如下圖所示,對于person,通過cn和sn設(shè)置用戶的名和姓,這是必須設(shè)置的,而其他屬性則是可選的。
下面列出部分常用objectClass要求必設(shè)的屬性。
● account:userid。
● organization:o。
● person:cn和sn。
● organizationalPerson:與person相同。
● organizationalRole:cn。
● organizationUnit:ou。
● posixGroup:cn、gidNumber。
● posixAccount:cn、gidNumber、homeDirectory、uid、uidNumber。
4.創(chuàng)建LDIF文件
對以上內(nèi)容有一定了解之后,就可以編寫輸入LDIF文件,編輯需要向目錄數(shù)據(jù)庫添加的條目了。
下面根據(jù)如下圖所示的結(jié)構(gòu),創(chuàng)建LDIF文件dlw.com.ldif。
對上圖進(jìn)行分析,該目錄結(jié)構(gòu)分為3層,有4個(gè)結(jié)點(diǎn)。根據(jù)上圖可創(chuàng)建LDIF文件如下:
提示:每個(gè)結(jié)點(diǎn)可用一個(gè)dn表示,對于每個(gè)結(jié)點(diǎn),又可繼續(xù)添加新的結(jié)點(diǎn)。如在根結(jié)點(diǎn)中可添加其他部門ou,在ou=managers結(jié)點(diǎn)也可繼續(xù)添加其他管理人員的信息。
寫道
1: dn:dc=dlw,dc=com
2: objectclass:top
3: objectclass:dcobject
4: objectclass:organization
5: dc:dlw
6: o:dlw,Inc.
7:
8: dn:ou=managers, dc=dlw, dc=com
9: ou:managers
10: objectclass:organizationalUnit
11:
12: dn:cn=dlw,ou=managers,dc=dlw,dc=com
13: cn:dlw
14: sn:dongliwei
15: objectclass:person
16:
17: dn:cn=test,ou=managers,dc=dlw,dc=com
18: cn:test
19: sn:Test User
20: objectclass:person
以上文件中各行的含義如下:
第1~6行創(chuàng)建根結(jié)點(diǎn),這部分在前面也有介紹,就不再重復(fù)了。
第7、11、16行為空行,用來分隔4個(gè)dn條目(4個(gè)結(jié)點(diǎn))。
第8~10行定義cn=managers結(jié)點(diǎn)的條目,該條目的objectClass為organizationalUnit,因此需要用ou屬性定義組織名稱。
第12~15行定義cn=dlw結(jié)點(diǎn)的條目,該條目使用的objectClass為person,因此需設(shè)置cn和sn兩個(gè)屬性值。
第17~20行與第12~15行的意義相同。
在以上LDIF文件中,第1、8、12、17行以dn開頭,這部分內(nèi)容必須唯一,并且在向目錄數(shù)據(jù)庫添加這些數(shù)據(jù)時(shí),也要確保這些數(shù)據(jù)不能與目錄數(shù)據(jù)庫中已有數(shù)據(jù)相同,否則,添加操作將中斷。
5.從LDIF文件添加到目錄數(shù)據(jù)庫
使用OpenLDAP客戶端工具ldapadd命令,可將LDIF文件中的條目添加到目錄數(shù)據(jù)庫中,該命令的格式如下:
ldappadd 選項(xiàng) LDIF文件
在ldappadd命令中常用的選項(xiàng)如下:
-x:進(jìn)行簡單認(rèn)證。
-D:用來綁定服務(wù)器的dn。
-h:目錄服務(wù)的地址。
-w:綁定dn的密碼。
-f:使用LDIF文件進(jìn)行條目添加的文件。
將前面編寫的LDIF文件的條目數(shù)據(jù)添加到目錄數(shù)據(jù)庫中。
具體操作步驟如下:
(1)檢查dlw.com.ldif文件中的內(nèi)容,需要注意的是,每個(gè)冒號(hào)后面都需要空一格,而每行結(jié)束處不能留有空格字符。
(2)使用以下命令將dlw.com.ldif文件中的條目添加到目錄中:
寫道
# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f dlw.com.ldif
執(zhí)行以上命令,如果添加操作正常完成,將顯示如下圖所示的提示信息,表示添加了4個(gè)條目到目錄數(shù)據(jù)庫中。
提示:如果以上命令執(zhí)行不成功,需要逐個(gè)字符檢查dlw.com.ldif文件中的內(nèi)容,特別注意空格的問題。
查詢
添加到目錄中的條目被保存在目錄數(shù)據(jù)庫,在Linux命令界面下,可使用OpenLDAP客戶端工具ldapsearch命令來進(jìn)行查詢。該命令的格式如下:
ldapsearch 選項(xiàng) 過濾 屬性值
常用的選項(xiàng)有以下幾個(gè):
● -x:進(jìn)行簡單認(rèn)證。
● -D:用來綁定服務(wù)器的dn。
● -w:綁定dn的密碼。
● -b:指定要查詢的根節(jié)點(diǎn)。
● -H:制定要查詢的服務(wù)器。
使用ldapsearch命令查詢“dc=dlw, dc=com”下的所有條目,可使用以下命令:
Python代碼
# ldapsearch -x -b "dc=dlw,dc=com"
執(zhí)行結(jié)果如下圖所示。
而如果使用以下命令,將查詢顯示sn中以字符wu開頭的條目,將得到如下圖所示的查詢結(jié)果,只找到一個(gè)條目。
Python代碼
# ldapsearch -x -b 'dc=dlw,dc=com' 'sn=wu*'
修改條目
使用OpenLDAP客戶端工具ldapmodify命令可對目錄數(shù)據(jù)庫中的條目進(jìn)行修改。該命令的格式如下:
ldapmodify 選項(xiàng)
該命令的選項(xiàng)也很多,常用選項(xiàng)與ldapadd類似,這里就不再列出了。
提示:使用ldapmodify命令不能修改條目的dn,但可以修改其他屬性值。
使用ldapmodify命令修改條目信息可以有兩種方式:一種是交互式進(jìn)行修改,另一種是通過文件進(jìn)行修改。
1.交互式修改
修改前面創(chuàng)建的條目“cn=test, ou=managers, dc=dlw, dc=com”,將其sn屬性修改為“Test User Modify”,并添加一個(gè)description屬性,設(shè)置其值為“add Attribute”。
首先輸入以下命令,進(jìn)行修改狀態(tài):
Python代碼
# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -W secret
執(zhí)行以上命令后,終端將等候用戶輸入需要修改條目的dn,輸入以下內(nèi)容:
Python代碼
dn: cn=test, ou=managers, dc=dlw, dc=com
changetype: modify
replace: sn
sn: Test User Modify
以上輸入內(nèi)容中,第1行查找需要修改的條目,第2行設(shè)置修改模式,第3行設(shè)置需要替換的屬性sn,第4行給屬性sn重新設(shè)置一個(gè)值,替換該屬性原有的值。
輸入完以上內(nèi)容之后再按Enter鍵,程序?qū)匆陨显O(shè)置更新數(shù)據(jù),然后按Ctrl+C鍵退出修改命令。執(zhí)行過程如下圖所示。
使用以上命令修改條目的數(shù)據(jù)之后,可使用以下命令查看是否修改成功:
Python代碼
#ldapsearch -x -b 'dc=dlw,dc=com' 'cn=test'
執(zhí)行以上命令查看test條目的數(shù)據(jù)如下圖所示,可以看到sn屬性被修改了。
2.通過文件修改
通過前面的方式對條目進(jìn)行修改時(shí),很不方便,如果在交互方式時(shí)輸錯(cuò)了某個(gè)字符,只能中斷命令后重新進(jìn)行修改。因此,更好的修改方法是首先將修改時(shí)輸入的文字保存到一個(gè)文件中,然后以該文件作為輸入進(jìn)行修改。用這種方式進(jìn)行操作,首先需要?jiǎng)?chuàng)建一個(gè)臨時(shí)文件,用來保存需要進(jìn)行的修改操作,下面演示這種方式的修改過程。
【例子】 通過修改命令將前面LDAP數(shù)據(jù)庫中的信息還原,即將sn屬性由“Test User Modify”修改為“Test User”。
具體操作步驟如下:
(1)使用vi編輯器創(chuàng)建一個(gè)文件modify,在其中輸入以下內(nèi)容:
Python代碼
dn: cn=test,ou=managers,dc=dlw,dc=com
changetype: modify
replace: sn
sn: Test User
從以上輸入內(nèi)容可看到,與在交互式時(shí)輸入的內(nèi)容完全相同。
技巧:使用文件方式修改條目,可方便修改和檢查,若某個(gè)地方有輸入錯(cuò)誤,可修改后再調(diào)用ldapmodify進(jìn)行修改,減少輸入量。
(2)使用以下命令調(diào)用modify的內(nèi)容進(jìn)行修改:
Python代碼
# ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret -f modify
執(zhí)行結(jié)果如下圖所示。
刪除條目
對于目錄數(shù)據(jù)庫中不用的條目,也可使用ldapdelete命令將其刪除。該命令的格式如下:
ldapdelete 選項(xiàng) 刪除條目
該命令使用的選項(xiàng)與ldapadd類似,就不再列出來了。
刪除目錄數(shù)據(jù)庫中的“cn=test,ou=managers,dc=dlw,dc=com”條目,具體命令如下:
Python代碼
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret \
> "cn=test,ou=managers,dc=dlw,dc=com"
順利執(zhí)行以上命令后,終端上將不會(huì)有任何信息輸出,表示完成了刪除操作。
使用ldapdelete命令只能刪除樹形結(jié)構(gòu)中的葉結(jié)點(diǎn)條目,如果刪除非葉結(jié)點(diǎn)條目,將出現(xiàn)錯(cuò)誤提示。例如,執(zhí)行以下命令刪除根結(jié)點(diǎn)“dc=dlw,dc=com”,由于根結(jié)點(diǎn)下面還有結(jié)點(diǎn),將顯示如下圖所示的錯(cuò)誤提示信息:
Python代碼
# ldapdelete -x -D "cn=root,dc=dlw,dc=com" -w secret "dc=dlw,dc=com"
數(shù)據(jù)導(dǎo)出
通過ldapadd命令可向目錄數(shù)據(jù)庫中添加數(shù)據(jù),在某些情況下,可能還需要進(jìn)行反向操作,即將目錄數(shù)據(jù)庫中的數(shù)據(jù)導(dǎo)出。
使用ldapsearch命令對目錄數(shù)據(jù)庫進(jìn)行搜索,然后通過重定向?qū)⑺阉鹘Y(jié)果保存到一個(gè)文件中,可達(dá)到導(dǎo)出數(shù)據(jù)的目的。另外,導(dǎo)出數(shù)據(jù)更常用的是slapcat命令,該命令的格式如下:
slapcat 選項(xiàng)
最常用的選項(xiàng)就是-l,表示導(dǎo)出為LDIF文件格式。
如將本章前面例子中創(chuàng)建的目錄數(shù)據(jù)庫導(dǎo)出為export.ldif文件,可使用以下命令:
Python代碼
#slapcat -l export.ldif
執(zhí)行以上命令將在當(dāng)前工作目錄得到文件export.ldif,打開文件將顯示如下圖所示的內(nèi)容:
提示:從導(dǎo)出結(jié)果可看出,除了使用ldapadd命令添加到目錄數(shù)據(jù)庫中的條目數(shù)據(jù)外,還導(dǎo)出了很多其他信息,包括條目錄UUID、時(shí)間戳等信息。
設(shè)置主從LDAP服務(wù)器
在某些時(shí)候,為了對LDAP服務(wù)器進(jìn)行負(fù)載均衡,可能希望設(shè)置多臺(tái)LDAP服務(wù)器。對于設(shè)置多臺(tái)LDAP服務(wù)器的關(guān)鍵問題是數(shù)據(jù)的同步問題,使用slurpd進(jìn)程可進(jìn)行主LDAP服務(wù)器向從LDAP服務(wù)器復(fù)制數(shù)據(jù)的操作。下面將介紹架設(shè)主從LDAP服務(wù)器的過程。
多臺(tái)LDAP服務(wù)器工作過程
對于多臺(tái)LDAP服務(wù)器,可設(shè)置一臺(tái)為主服務(wù)器,其他的為從服務(wù)器。本節(jié)介紹一臺(tái)從服務(wù)器的配置,若是多臺(tái)從服務(wù)器也可按此步驟進(jìn)行操作。
注意:在進(jìn)行配置之前應(yīng)首先確保每個(gè)LDAP服務(wù)器都已安裝好OpenLDAP服務(wù)器程序,并能正確工作。
通過本節(jié)下面介紹的方法配置好主從LDAP服務(wù)器之后,在主服務(wù)器運(yùn)行slurpd進(jìn)程,該進(jìn)程使用LDAP協(xié)議從主服務(wù)器的數(shù)據(jù)庫更新從服務(wù)器的數(shù)據(jù),具體操作過程如下:
(1)LDAP客戶端向從服務(wù)器提交一個(gè)LDAP修改請求。
(2)從服務(wù)器給LDAP客戶端返回一個(gè)指向主服務(wù)器的引用。
(3)LDAP客戶端向主服務(wù)器提交LDAP修改請求。
(4)主服務(wù)器對數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行修改,并將改變寫入本機(jī)的日志文件。
(5)在主服務(wù)器運(yùn)行的slurpd進(jìn)程檢查到日志中有新內(nèi)容,通過日志的信息將改變發(fā)送給從服務(wù)器。
(6)從服務(wù)器接收slurpd發(fā)來的信息,對本地?cái)?shù)據(jù)進(jìn)行修改。
以上過程就是使用slurpd進(jìn)程進(jìn)行數(shù)據(jù)復(fù)制的過程。從以上過程可看出,需要在主服務(wù)器的配置文件中設(shè)置要向哪些從服務(wù)器發(fā)送復(fù)制信息、主服務(wù)器還要設(shè)置一個(gè)記錄數(shù)據(jù)改變的日志文件,而從服務(wù)器需要設(shè)置一個(gè)指向主服務(wù)器的鏈接。
復(fù)制數(shù)據(jù)庫
首先,把主從服務(wù)器關(guān)閉。通過以下三步操作靜態(tài)同步主從服務(wù)器上的數(shù)據(jù):
把主服務(wù)器上/var/lib/ldap目錄下的所有數(shù)據(jù)庫文件全部拷貝到從服務(wù)器的同目錄中,覆蓋原有文件。
把主服務(wù)器上的/etc/ldap/schema目錄下的所有schema文件拷貝到從服務(wù)器的同目錄中,覆蓋原有文件。
把主服務(wù)器上/etc/ldap/slapd.conf文件拷貝到從服務(wù)器的同目錄中,覆蓋原有文件。
設(shè)置主服務(wù)器
配置主服務(wù)器上的slapd.conf文件,取消replogfile指令前的注釋符號(hào),取消后的結(jié)果如下:
Python代碼
# Replicas of this database
replogfile /var/lib/ldap/replog
增加replica指令,如:
Python代碼
#replace config
replica uri=ldap://192.168.14.21:389 #指定從服務(wù)器主機(jī)名和端口號(hào)
binddn="cn=root,dc=dlw,dc=com" #指定需同步的DN的管理員
bindmethod=simple credentials=111111 #指定驗(yàn)證方式和需同步的DN的管理員密碼
設(shè)置從服務(wù)器
配置從服務(wù)器上的slapd.conf文件,增加updatedn指令,如:
Python代碼
updatedn " cn=root,dc=dlw,dc=com" #與主服務(wù)器的binddn對應(yīng)
在從服務(wù)器的配置文件中,不要包含replica和replogfile指令。
測試主從LDAP服務(wù)器
經(jīng)過以上步驟的操作,主從LDAP服務(wù)器都已準(zhǔn)備好,接下來就可以測試相關(guān)操作。
1.啟動(dòng)主LDAP服務(wù)器
在主LDAP服務(wù)器中啟動(dòng)slapd進(jìn)程和slurpd進(jìn)程。
2.啟動(dòng)從LDAP服務(wù)器
在主LDAP服務(wù)器中啟動(dòng)slapd進(jìn)程。
【例子】測試主從LDAP服務(wù)器。
具體操作步驟如下:
(1)在主LDAP服務(wù)器中使用以下命令修改一個(gè)條目:
Python代碼
#ldapmodify -x -D "cn=root,dc=dlw,dc=com" -w secret
輸入以下內(nèi)容,修改cn=dlw條目的內(nèi)容:
Python代碼
dn: cn=dlw,ou=managers,dc=dlw,dc=com
changetype: modify
replace: sn
sn: dongliwei
輸入后按Enter鍵完成修改,操作過程如圖5-7所示(將sn修改為dongliwei)。
(2)在從LDAP服務(wù)器中進(jìn)行操作,查看主LDAP服務(wù)器中的操作是否被復(fù)制到從LDAP服務(wù)器中來了。在從LDAP服務(wù)器中使用以下命令進(jìn)行查詢:
Python代碼
#ldapsearch -x -b "dc=dlw,dc=com" "cn=dlw"
執(zhí)行結(jié)果如下圖所示,從圖中可看到其中的sn也被修改為dongliwei了(數(shù)據(jù)庫中原來的內(nèi)容為zhangsan.modi,是前面例子中修改的值),即被主LDAP服務(wù)器進(jìn)行了同步復(fù)制。
OpenLDAP在用戶認(rèn)證的應(yīng)用
OpenLDAP經(jīng)常用在用戶登錄認(rèn)證方面,通過LDAP的數(shù)據(jù)復(fù)制功能,可讓用戶使用一個(gè)賬戶登錄網(wǎng)絡(luò)中使用LDAP服務(wù)的所有服務(wù)器。在主LDAP服務(wù)器中設(shè)置好用戶賬戶數(shù)據(jù),然后通過在網(wǎng)絡(luò)中的任意客戶端都可使用設(shè)置的賬號(hào)進(jìn)行登錄操作。下面將簡單介紹將用戶認(rèn)證遷移到LDAP的操作方法。
用戶認(rèn)證用到的ojbectClass
在LDAP中用來保存用戶認(rèn)證條目的objectClass主要有以下3個(gè),分別用來保存組、用戶、密碼等信息到目錄的條目中。
posixGroup:可設(shè)置屬性cn、userPassword、gidNumber等。
posixAccount:可設(shè)置屬性cn、gidNumber、uid、uidNumber、homeDirectory、loginShell等。
shadowAccount:可設(shè)置屬性uid、shadowExpire、shadowFlag、shadowInactive、shadowLastChange、shadowMax、shadowMin、shadowWarning、userPassword等。
提示:從上面列出的屬性的名稱可以很容易地與組、用戶的相關(guān)信息聯(lián)系起來。
使用遷移工具
要使用LDAP進(jìn)行用戶認(rèn)證,首先應(yīng)該考慮的就是數(shù)據(jù)遷移的工作量。如果要操作員從/etc/passwd和/etc/group文件中逐個(gè)將信息重新錄入,工作量將非常大。
OpenLDAP為用戶考慮到了這些遷移工作,提供了多個(gè)遷移工具的腳本程序,這些程序位于/usr/share/openldap/migration/目錄中,在該目錄中有很多擴(kuò)展名為pl和sh的腳本文件,通過這些遷移工具,可以很方便地將系統(tǒng)中的用戶遷移到LDAP目錄數(shù)據(jù)庫中。下面介紹具體的遷移步驟。
【例子】將系統(tǒng)中的用戶信息遷移到LDAP目錄數(shù)據(jù)庫中。
具體操作步驟如下:
(1)修改/usr/share/openldap/migration/migrate_common.ph文件,在其中查找以下內(nèi)容:
Python代碼
$DEFAULT_BASE="dc=padl,dc=com";
將其修改為目錄服務(wù)器使用的根,如本章使用的例子要改為以下形式:
Python代碼
$DEFAULT_BASE="dc=dlw,dc=com";
保存后退出。
(2)使用以下命令執(zhí)行腳本migrate_base.pl,用來創(chuàng)建根項(xiàng),并為Hosts、Networks、Group和People等創(chuàng)建低一級的組織單元(執(zhí)行該命令將生成base.ldif文件):
Python代碼
#./migrate_base.pl > base.ldif
(3)由于本章前面已在LDAP服務(wù)器中創(chuàng)建了根項(xiàng)“dc=dlw,dc=com”,因此將base.ldif文件中的第1個(gè)條目刪除,另外,在用戶認(rèn)證中只用到組和用戶,也將其他無關(guān)條目刪除,只保存以下內(nèi)容(例子):
Python代碼
dn: ou=People,dc=dlw,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit
dn: ou=Group,dc=dlw,dc=com
ou: Group
objectClass: top
objectClass: organizationalUnit
(4)使用以下命令將base.ldif文件中的條目導(dǎo)入目錄數(shù)據(jù)庫:
Python代碼
# ldapadd -x -D "cn=root,dc=dlw,dc=com" -w secret -f base.ldif
執(zhí)行結(jié)果如下圖所示。
(5)開始遷移組信息。使用以下命令將/etc/group中的組信息保存到臨時(shí)文件group.tmp中:
Python代碼
#cat /etc/group > group.tmp
(6)系統(tǒng)組不導(dǎo)入LDAP目錄數(shù)據(jù)庫中,因此需對group.tmp文件中的信息進(jìn)行編輯,只保留需要導(dǎo)入LDAP目錄數(shù)據(jù)庫的組的信息。
(7)使用以下命令將組的數(shù)據(jù)生成LDIF條目信息:
Python代碼
#./migrate_group.pl group.tmp > group.ldif
(8)使用cat命令查看group.ldif的內(nèi)容,可看到已按posixGroup這種objectClass將組的數(shù)據(jù)組織完成,如下圖所示。
(9)類似地,使用以下命令導(dǎo)出/etc/passwd中的用戶數(shù)據(jù),并刪除不需要的用戶,然后使用migrate_passwd.pl腳本生成LDIF文件:
Python代碼
#cat /etc/passwd > passwd.tmp
#./migrate_passwd.pl passwd.tmp > passwd.ldif
#cat passwd.ldif
提示:從上面列出的屬性的名稱可以很容易地與組、用戶的相關(guān)信息聯(lián)系起來。
(10)使用以下命令將組和用戶信息導(dǎo)入目錄數(shù)據(jù)庫:
Python代碼
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f group.ldif
#ldapadd -x -D "cn=root,dc=dlw,dc=com" -w 111111 -f passwd.ldif
執(zhí)行以上命令的過程如下圖所示。
(11)使用以下命令查看目錄數(shù)據(jù)庫中用戶root的信息,用“uid=root”作查詢條件:
Python代碼
#ldapsearch -x -b 'dc=dlw,dc=com' 'uid=root'
查找結(jié)果如下圖所示。
通過以上的操作,就將需要導(dǎo)入的組和用戶的信息導(dǎo)入到了目錄數(shù)據(jù)庫中,接下來還需要對客戶端進(jìn)行設(shè)置,使用LDAP進(jìn)行登錄驗(yàn)證操作。
設(shè)置客戶端登錄
若客戶端要使用LDAP進(jìn)行用戶登錄認(rèn)證,則可使用本地計(jì)算機(jī)中不存在的用戶名進(jìn)行登錄操作。
【例子】修改配置文件,設(shè)置客戶端使用LDAP進(jìn)行認(rèn)證。
具體操作步驟如下:
(1)修改客戶端計(jì)算機(jī)中的/etc/sysconfig/authconfig文件,將以下項(xiàng)都修改為yes:
Python代碼
USELDAP=yes
USELDAPAUTH=yes
USEMD5=no
USESHADOW=yes
USELOCAUTHORIZE=yes
(2)修改客戶端計(jì)算機(jī)中的/etc/openldap/ldap.conf文件,修改內(nèi)容如下:
Python代碼
host 192.168.14.20
BASE dc=dlw,dc=com
ssl off
(3)修改客戶端計(jì)算機(jī)中的/etc/nsswitch.conf文件,在passwd、shadow、group后面都加上ldap,如下圖所示。
經(jīng)過以上配置以后,在客戶端就可以使用LDAP目錄數(shù)據(jù)庫中的用戶信息在客戶端進(jìn)行登錄操作了。登錄操作與使用本地用戶賬號(hào)相同,這里就不再演示了。
LDAP Schema
Schema是LDAP的一個(gè)重要組成部分,類似于數(shù)據(jù)庫的模式定義,LDAP的Schema定義了LDAP目錄所應(yīng)遵循的結(jié)構(gòu)和規(guī)則,比如一個(gè) objectclass會(huì)有哪些屬性,這些屬性又是什么結(jié)構(gòu)等等,schema給LDAP服務(wù)器提供了LDAP目錄中類別,屬性等信息的識(shí)別方式,讓這些可以被LDAP服務(wù)器識(shí)別。
在LDAP的schema中,有四個(gè)重要的元素:
Objectclass
objectclass定義了一個(gè)類別,這個(gè)類別會(huì)被不同的目錄(在LDAP中就是一個(gè)Entry)用到,它說明了該目錄應(yīng)該有哪些屬性,哪些屬性是必須的,哪些又是可選的。一個(gè)objectclass的定義包括名稱(NAME),說明(DESC),類型(STRUCTURAL或AUXILARY ,表示是結(jié)構(gòu)型的還是輔助型的),必須屬性(MUST),可選屬性(MAY)等信息。
Python代碼
Objectclass格式:
objectclass = ( whsp
numericoid whsp //全局唯一的 OID
[ "NAME" qdescrs ] //類名稱
[ "DESC" qdstring ] //類描述
[ "OBSOLETE" whsp ]
[ "SUP" oids ] ; //父類
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
[ "MUST" oids ] ; //必填屬性集合
[ "MAY" oids ] //選填屬性集合
whsp ")"
例如:
Python代碼
# Object Class Definitions
objectclass ( 1.3.6.1.4.1.7914.1.2.2.1 NAME 'kunmailUser'
DESC 'KunMail-LDAP User'
SUP top
STRUCTURAL
MUST(username$cn$vuid$vgid)
MAY(maildir$home$clearpw$forwardAddr$quota$storeHost$delivery$mailReplyText$active))
這里kunmailUser這種數(shù)據(jù),要包含maildir $ home $ clearpw $ forwardAddr $ quota $ storeHost $ delivery $ mailReplyText $ active等可選項(xiàng),還要包括username $ cn $ vuid $ vgid 必選項(xiàng)。 可選項(xiàng)用MAY()來包含,必選項(xiàng)用MUST()來包含。DESC是說明項(xiàng)。SUP表示父類(有點(diǎn)像面向?qū)ο缶幊贪。﹖op表示沒有父類,他自己是頂級。STRUCTURAL是存儲(chǔ)方式。一般來說每個(gè)節(jié)點(diǎn)都要包含一個(gè)ABSTRACT類("top" or "alias"), 至少一個(gè)STRUCTURAL類,0個(gè)或者多個(gè)AUXILIARY類。AUXILIARY表示輔助型、STRUCTURAL表示結(jié)構(gòu)型(默認(rèn))、ABSTRACT表示摘要型。
下面定義一個(gè)允許將myPhoto增加到任何已經(jīng)存在的條目中的auxiliary對象類:
Python代碼
objectclass= ( 1.1.2.2.1 NAME 'myPhotoObject'
DESC 'mixin myPhoto'
AUXILIARY
MAY myPhoto )
如果您的組織需要一個(gè)私有的結(jié)構(gòu)化對象類來表示用戶,你可以子類化任何一個(gè)已經(jīng)存在的person類,比如inetOrgPerson(RFC2798),然后增加需要的屬性:
Python代碼
objectclass =( 1.1.2.2.2 NAME 'myPerson'
DESC 'my person'
SUP inetOrgPerson
MUST ( 'myUniqueName' $ 'givenName' )
MAY 'myPhoto' )
該對象類從inetOrgPerson中繼承允許的或者必須的屬性,但是,要求myUniqueName和givenName,允許myPhoto。
Attribute
attribute就是一個(gè)上面objectclass中可能包含的屬性,對其的定義包括名稱,數(shù)據(jù)類型,單值還是多值以及匹配規(guī)則等。后面用具體的例子來說明。
Attribute格式:
Python代碼
attributeType ( whsp
numericoid whsp //全局唯一的 OID
[ "NAME" qdescrs ] //屬性名稱
[ "DESC" qdstring ] //屬性描述
[ "OBSOLETE" whsp ]
[ "SUP" woid ] //本屬性從其它屬性中派生出來的
[ "EQUALITY" woid //相等性匹配
[ "ORDERING" woid//順序匹配
[ "SUBSTR" woid ] //字符串匹配
[ "SYNTAX" whsp noidlen whsp ] //字段的數(shù)據(jù)類型的OID
[ "SINGLE-VALUE" whsp ] //定義本屬性為單值(默認(rèn)多值)
[ "COLLECTIVE" whsp ] //default not collective
[ "NO-USER-MODIFICATION" whsp ]//default user modifiable
[ "USAGE" whsp AttributeUsage ]//default userApplications
whsp ")"
AttributeUsage =
"userApplications" /
"directoryOperation" /
"distributedOperation" / ; DSA-shared
whsp是空格的意思(' ')。numericoid 是全局唯一的 OID,是帶.的十進(jìn)制形式 (e.g. 1.1.0), qdescrs有一個(gè)或幾個(gè)意思, woid 可以使名稱或者是 OID 可選擇的一定長度的后綴(e.g {10})。
例如,屬性類型name和cn在core.schema中如下定義:
Python代碼
attributeType ( 2.5.4.41 NAME 'name'
DESC 'name(s) associated with the object'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
attributeType ( 2.5.4.3 NAME ( 'cn' $ 'commonName' )
DESC 'common name(s) assciated with the object'
SUP name )
attributetype ( 1.3.6.1.4.1.7914.1.2.1.6 NAME 'quota'
DESC 'The amount of space the user can use until all further messages get bounced.'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.44
SINGLE-value )
請注意,每一個(gè)都定義了屬性的OID,給出了一個(gè)短的名稱,以及一個(gè)簡短的描述。每一個(gè)名稱都是OID的一個(gè)別名。Slapd(8)在返回結(jié)果的時(shí)候,將返回第1個(gè)列出的名稱。
第1個(gè)名稱,name,保存了directoryString(UTF-8編碼的Unicode)語法。該語法由OID說明。(1.3.6.1.4.1.1466.115.121.1.15標(biāo)識(shí)了目錄字符串語法)。還說明了一個(gè)推薦長度為32768的選項(xiàng)。服務(wù)器應(yīng)該支持該長度的值,但是,也可以支持更長的值。該域沒有指明長度限制,因此,在服務(wù)器上被忽略,并且服務(wù)器不會(huì)限制其大小。另外,相等和子串匹配使用不區(qū)分大小寫的規(guī)則。下面是經(jīng)常使用的語法和匹配規(guī)則(OpenLDAP支持這些,以及更多)
第2個(gè)屬性,cn,是name的一個(gè)子類型,因此,它繼承了語法,匹配規(guī)則,并且使用name.commonName作為別名。
兩個(gè)屬性都沒有限制到單一值。都可以被用戶應(yīng)用程序所使用,都不存在過期,都不是集合。
很多組織為用戶保留唯一的名字(unique name),雖然用戶可以使用displayName,但是這個(gè)屬性(name)依舊由用戶控制。而不是organization。我們可以從 inetorgperson.schema 拷貝displayName ,替換OID,name,和描述(description)。
Python代碼
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
DESC 'unique name with my organization'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )
但是,如果我們要使name屬性包含一個(gè)斷言,這個(gè)屬性可以被定義為name的子屬性。
Python代碼
attributetype ( 1.1.2.1.1 NAME 'myUniqueName'
DESC 'unique name with my organization'
SUP name )
很多的組織為每一個(gè)用戶保留一個(gè)頭像。myPhoto屬性類型的定義可以用來保存用戶的頭像。當(dāng)然用戶可以選擇jpegPhoto屬性類型(RFC2798)(或其子類型)來保存頭像。當(dāng)然你只能在圖片符合JPEG File Interchange Format時(shí)使用。
當(dāng)然,一個(gè)使用八進(jìn)制語法的屬性類型可以這樣的定義:
Python代碼
attributetype ( 1.1.2.1.2 NAME 'myPhoto'
DESC 'a photo (application defined format)'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
SINGLE-VALUE )
在這,語法中并沒有置頂photo的格式(format),這里假設(shè)訪問屬性的應(yīng)用可以對其值進(jìn)行處理。
如果你想支持多種圖片格式,你需要為每一個(gè)格式定義屬性類型。為圖片添加類型信息的前綴。或者使用ASN.1描述值,和use the ;binary transfer option。
可以使圖片屬性能夠保存URI,你可以在labeledURI(RFC2079)后創(chuàng)建一個(gè)屬性,或者創(chuàng)建一個(gè)子類型。
Python代碼
attributetype ( 1.1.2.1.3 NAME 'myPhotoURI'
DESC 'URI and optional label referring to a photo'
SUP labeledURI )
Syntax
syntax是LDAP中的“語法”,其實(shí)就是LDAP中會(huì)用到的數(shù)據(jù)類型和數(shù)據(jù)約束,這個(gè)語法是遵從X.500中數(shù)據(jù)約束的定義的。其定義需要有一個(gè)ID(遵從X.500)以及說明(DESP)
Commonly Used Syntaxes
Name
OID
Description
boolean
1.3.6.1.4.1.1466.115.121.1.7
boolean value
distinguishedName
1.3.6.1.4.1.1466.115.121.1.12
DN
directoryString
1.3.6.1.4.1.1466.115.121.1.15
UTF-8 string
IA5String
1.3.6.1.4.1.1466.115.121.1.26
ASCII string
Integer
1.3.6.1.4.1.1466.115.121.1.27
integer
Name and Optional UID
1.3.6.1.4.1.1466.115.121.1.34
DN plus UID
Numeric String
1.3.6.1.4.1.1466.115.121.1.36
numeric string
OID
1.3.6.1.4.1.1466.115.121.1.38
object identifier
Octet String
1.3.6.1.4.1.1466.115.121.1.40
arbitary octets
Printable String
1.3.6.1.4.1.1466.115.121.1.44
printable string
Matching Rules
是用來指定某屬性的匹配規(guī)則,實(shí)際上就是定義一個(gè)特殊的Syntax的別名,讓LDAP服務(wù)器可以識(shí)別,并對定義的屬性進(jìn)行匹配。
Commonly Used Matching Rules
Name
Type
Description
booleanMatch
equality
boolean
octetStringMatch
equality
octet string
objectIdentiferMatch
equality
OID
distinguishedNameMatch
equality
DN
uniqueMemberMatch
equality
Name with optional UID
numericStringMatch
equality
numerical
numericStringOrderingMatch
ordering
numerical
numericStringSubstringsMatch
substrings
numerical
caseIgnoreMatch
equality
case insensitive, space insensitive
caseIgnoreOrderingMatch
ordering
case insensitive, space insensitive
caseIgnoreSubstringsMatch
substrings
case insensitive, space insensitive
caseExactMatch
equality
case sensitive, space insensitive
caseExactOrderingMatch
ordering
case sensitive, space insensitive
caseExactSubstringsMatch
substrings
case sensitive, space insensitive
caseIgnoreIA5Match
equality
case insensitive, space insensitive
caseIgnoreIA5OrderingMatch
ordering
case insensitive, space insensitive
caseIgnoreIA5SubstringsMatch
substrings
case insensitive, space insensitive
caseExactIA5Match
equality
case sensitive, space insensitive
caseExactIA5OrderingMatch
ordering
case sensitive, space insensitive
caseExactIA5SubstringsMatch
substrings
case sensitive, space insensitive
LDAP的schema的主要元素就是這些了,下面列舉出了一些LDAP規(guī)定好的或是現(xiàn)在比較通用的schema,一般的LDAP服務(wù)器都應(yīng)該可以識(shí)別這些定義。
這就是一個(gè)名為subschema的objectclass的定義:
Python代碼
objectclass=(2.5.20.1 NAME 'subschema' AUXILIARY
MAY ( dITStructureRules $ nameForms $ ditContentRules $
objectClasses $ attributeTypes $ matchingRules $ matchingRuleUse ) )
首先是ID,這里是2.5.20.1,接著是NAME,AUXILIARY說明是輔助型,之后是可選屬性的定義,subschema中沒有定義必須屬性,如果需要定義,應(yīng)該和MAY一樣,將屬性放在MUST()中并用$隔開
再來看一個(gè)屬性定義:
Python代碼
attributetype ( 2.5.4.3 NAME 'cn' SUP name EQUALITY caseIgnoreMatch )
可以看到cn屬性的父屬性是name,它相等性匹配于caseIgnoreMatch(匹配原則為EQUALITY,還有如SUBSTR是字符串匹配,ORDERING是順序匹配)
syntax定義一般都比較簡單,如:
Python代碼
( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'String' )
這個(gè)定義說明,這一串?dāng)?shù)字1.3.6.1.4.1.1466.115.121.1.5就代表了LDAP中的字符串,這個(gè)數(shù)字串的定義和X.500相關(guān),包括了它的存儲(chǔ)方式,所占空間大小等。
最后看看Matching Rule的例子,前面提到了caseIgnoreMatch,就看他的吧
Python代碼
attributetype ( 2.5.13.2 NAME 'caseIgnoreMatch'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
其實(shí)1.3.6.1.4.1.1466.115.121.1.15 就是LDAP數(shù)據(jù)類型Directory String的ID,說明前面的cn需要等于這個(gè)數(shù)據(jù)類型才有效。
還有很多常用schema的定義都在了RFC2252中,LDAP服務(wù)器都應(yīng)該支持這些基本的schema。好了,現(xiàn)在基本對LDAP中的schema有個(gè)一個(gè)大致的說明,可能有不到位或不妥之處,還望大家指正。