openldap简介
安装就不说了,从配置开始说起
1.主要配置文件slapd.conf
内容包括三类:global, backend specific, and database specific。指全局设置,后台服务器的设置,数据库的设置。
全局的设置可以被另外两个的设置覆盖。后台服务器设置可以被数据库的设置覆盖。数据库设置可能是多个。
1.1全局设置
1.1.1 授权
#给不同的用户不同的权限,相当于数据库中的角色,权限一块
access to <what></what>[ by <who></who><accesslevel></accesslevel><control></control>]+
完整的语法是:
olcAccess: <access directive=""></access>
<access directive=""></access>::= to <what></what>
[by <who></who><access></access><control></control>]+
<what></what>::= * |
[dn[.<basic-style></basic-style>]=<regex></regex> | dn.<scope-style></scope-style>=<dn></dn>]
[filter=<ldapfilter></ldapfilter>] [attrs=<attrlist></attrlist>]
<basic-style></basic-style>::= regex | exact
<scope-style></scope-style>::= base | one | subtree | children
<attrlist></attrlist>::= <attr></attr>[val[.<basic-style></basic-style>]=<regex></regex>] | <attr></attr>, <attrlist></attrlist>
<attr></attr>::= <attrname></attrname>| entry | children
<who></who>::= * | [anonymous | users | self
| dn[.<basic-style></basic-style>]=<regex></regex> | dn.<scope-style></scope-style>=<dn></dn>]
[dnattr=<attrname></attrname>]
[group[/<objectclass></objectclass>[/<attrname></attrname>][.<basic-style></basic-style>]]=<regex></regex>]
[peername[.<basic-style></basic-style>]=<regex></regex>]
[sockname[.<basic-style></basic-style>]=<regex></regex>]
[domain[.<basic-style></basic-style>]=<regex></regex>]
[sockurl[.<basic-style></basic-style>]=<regex></regex>]
[set=<setspec></setspec>]
[aci=<attrname></attrname>]
<access></access>::= [self]{<level></level>| <priv></priv> }
<level></level>::= none | auth | compare | search | read | write
<priv></priv> ::= {=|+|-}{w|r|s|c|x|0}+
<control></control>::= [stop | continue | break]
1.1.1.1 what
####################################################################
几种写法:
》》to * 所有目录,这和dn=.*写法是相同的
》》to dn[.<basic-style></basic-style>]=<regex></regex> 用正则表达式来匹配,basic-style不明白是什么意思
》》to dn.<scope-style></scope-style>=<dn></dn> scope可以是base, one, subtree, or children,
base就是要匹配目录是一样的,one匹配目标父亲目录是这里定义的DN。subtree匹配所有以这里定义的DN为root的子树。
children和subtree类似,只是少了和定义的DN相同的目录本身。
如:
0: o=suffix
1: cn=Manager,o=suffix
2: ou=people,o=suffix
3: uid=kdz,ou=people,o=suffix
4: cn=addresses,uid=kdz,ou=people,o=suffix
5: uid=hyc,ou=people,o=suffix
Then:
dn.base="ou=people,o=suffix" match 2;
dn.one="ou=people,o=suffix" match 3, and 5;
dn.subtree="ou=people,o=suffix" match 2, 3, 4, and 5; and
dn.children="ou=people,o=suffix" match 3, 4, and 5.
》》to filter=<ldap filter=""></ldap>
to dn.one="ou=people,o=suffix" filter=(objectClass=person)这两种作用是相同的
在what中还可以加对attribute的限制
attrs=<attribute list=""></attribute>
注意如果要增加、删除一个目录,需要有写该目录的attribute权限,同时还要有写该目录的父目录的children属性的权限。
1.1.1.2 who
Specifier Entities
----------------------------------------------------------------
* All, including anonymous and authenticated users
anonymous Anonymous (non-authenticated) users
users Authenticated users
self User associated with target entry
dn[.<basic-style></basic-style>]=<regex></regex> Users matching a regular expression
dn.<scope-style></scope-style>=<dn></dn> Users within scope of a DN
1.1.1.3 accesslevel
Level Privileges Description
----------------------------------------------------------------
none =0 no access
auth =x needed to bind
compare =cx needed to compare
search =scx needed to apply search filters
read =rscx needed to read search results
write =wrscx needed to modify/rename
每个级别的权限都包含了它所有以下级别的权限的
1.1.1.4 control
stop | continue | break
1.1.1.5 例子
olcAccess: to *
by self write
by anonymous auth
by * read
olcAccess: to dn.subtree="dc=example,dc=com" attr=homePhone
by self write
by dn.children=dc=example,dc=com" search
by peername.regex=IP:10\..+ read
olcAccess: to dn.subtree="dc=example,dc=com"
by self write
by dn.children="dc=example,dc=com" search
by anonymous auth
####################################################################
1.1.2
无
1.1.3 idletimeout <integer></integer>
以秒为单位,如果idle就强制断开client链接,默认是0,则关闭这个功能。
1.1.4 include <filename></filename>
#如果需要包含其他文件,这个要小心使用,注意嵌套include
在openldap的安装目录中的schema目录中可以看到以下几个安装后自带的文件,不要去修改,如果要自定义属性类型,
自己创建文件,并在slapd.conf文件中include进来就可以了。
File Description
--------------------------------------------------------------------
core.schema OpenLDAP core (required)
cosine.schema Cosine and Internet X.500 (useful)
inetorgperson.schema InetOrgPerson (useful)
misc.schema Assorted (experimental)
nis.schema Network Information Services (FYI)
openldap.schema OpenLDAP Project (experimental)
1.1.5 loglevel <integer></integer>
#LDAP记录日志的级别
####################################################################
Debugging Levels Level Description
------------------------------------------
-1 enable all debugging
0 no debugging
1 trace function calls
2 debug packet handling
4 heavy trace debugging
8 connection management
16 print out packets sent and received
32 search filter processing
64 configuration file processing
128 access control list processing
256 stats log connections/operations/results
512 stats log entries sent
1024 print communication with shell backends
2048 print entry parsing debugging
####################################################################
1.1.6 objectclass <rfc2252 class="" description="" object=""></rfc2252>
定义一个对象类,略。
1.1.7 referral <uri></uri>
如果slapd没办法找到数据库的时候转到URI
1.1.8 sizelimit <integer></integer>
设置一次search最多返回的entries数
1.1.9 timelimit <integer></integer>
以秒为单位,设置一次查询最多等待多少秒,超过时间,则返回,并表示超时。
1.2 backend设置
backend <type></type>
type的全部类型包括
Types Description
-------------------------------------
bdb Berkeley DB transactional backend
dnssrv DNS SRV backend
hdb Hierarchical variant of bdb backend
ldap Lightweight Directory Access Protocol (Proxy) backend
ldbm Lightweight DBM backend
meta Meta Directory backend
monitor Monitor backend
passwd Provides read-only access to passwd(5)
perl Perl Programmable backend
shell Shell (extern program) backend
sql SQL Programmable backend
1.3 General Database 设置
1.3.1 database <type></type>
这里的type和backend是相同的
1.3.2 readonly { on | off }
1.3.3 replica
设置复制数据库所在位置
replica uri=ldap[s]://<hostname></hostname>[: <port></port> ] | host=<hostname></hostname>[: <port></port> ]
[bindmethod={simple|sasl}]
["binddn=<dn></dn>"]
[saslmech=<mech></mech>]
[authcid=<identity></identity>]
[authzid=<identity></identity>]
[credentials= <password></password> ]
如果port没有写,是LDAP port默认的389 or 636。
slurpd负责复制数据库
1.3.4 replogfile <filename></filename>
如果有设置复制数据库,这里设置日志文件,slapd要记录数据库的改变。这个日志文件由slapd负责写,由slurpd读。
如果没有设置复制数据库,slurpd没有启动,也可以用这个文件来记录事务日志。
1.3.5 suffix <dn suffix=""></dn>
#设置目录后缀,还可以加更多的dc,如"dc=eng,dc=uni,dc=edu,dc=eu"
suffix "dc=example,dc=com"
1.3.6 rootdn <dn></dn>
#设置目录管理员
rootdn "cn=Manager,dc=example,dc=com"
1.3.7 rootpw <password></password>
rootpw secret
如果你不想把密码明文地写在这里,可以
rootpw {SSHA}ZKKuqbEKJfKSXhUbHG3fG8MDn9j1v4QN
格式是按RFC 2307 form,可以用命令slappasswd产生,如:slappasswd -s password
1.3.8 syncrepl复制引擎
说明此数据库是备份数据库,基于LDAP Content Synchronization protocol与主数据库同步的。
syncrepl rid=<replica id=""></replica> 长度不能超过3位
provider=ldap[s]://<hostname></hostname>[:port] 表明其主数据库地址
[type=refreshOnly|refreshAndPersist]
[interval=dd:hh:mm:ss]
[retry=[<retry interval=""></retry> <# of retries>]+]
[searchbase= <base dn="">]
[filter=<filter str=""></filter>]
[scope=sub|one|base]
[attrs=<attr list=""></attr>]
[attrsonly]
[sizelimit= <limit></limit> ]
[timelimit= <limit></limit> ]
[schemachecking=on|off]
[bindmethod=simple|sasl]
[binddn=<dn></dn>]
[saslmech=<mech></mech>]
[authcid=<identity></identity>]
[authzid=<identity></identity>]
[credentials= <passwd></passwd> ]
[realm=<realm></realm>]
[secprops= <properties></properties> ]</base>
1.3.9 updatedn <dn></dn>
仅对从库适用,从库可以修改的DN目录
1.3.10 updateref <url></url>
仅对从库适用,设置从库一旦有改变,返回给client的URL。
1.4 例子
1. # example config file - global configuration section
2. include /usr/local/etc/schema/core.schema
3. referral ldap://root.openldap.org
4. access to * by * read
5. # BDB definition for the example.com
6. database bdb
7. suffix "dc=example,dc=com"
8. directory /usr/local/var/openldap-data
9. rootdn "cn=Manager,dc=example,dc=com"
10. rootpw secret
11. # replication directives
12. replogfile /usr/local/var/openldap/slapd.replog
13. replica uri=ldap://slave1.example.com:389
14. binddn="cn=Replicator,dc=example,dc=com"
15. bindmethod=simple credentials=secret
16. replica uri=ldaps://slave2.example.com:636
17. binddn="cn=Replicator,dc=example,dc=com"
18. bindmethod=simple credentials=secret
19. # indexed attribute definitions
20. index uid pres,eq
21. index cn,sn,uid pres,eq,approx,sub
22. index objectClass eq
23. # database access control definitions
24. access to attr=userPassword
25. by self write
26. by anonymous auth
27. by dn.base="cn=Admin,dc=example,dc=com" write
28. by * none
29. access to *
30. by self write
31. by dn.base="cn=Admin,dc=example,dc=com" write
32. by * read
33. # BDB definition for example.net
34. database bdb
35. suffix "dc=example,dc=net"
36. directory /usr/local/var/openldap-data-net
37. rootdn "cn=Manager,dc=example,dc=com"
38. index objectClass eq
39. access to * by users read
2.启动slapd
启动slapd有很多参数
-f 配置文件
/usr/local/libexec/slapd -f /usr/local/etc/openldap/slapd.conf
-h <urls></urls>
配置监听的URL,可以是多个,默认ldap:// ,是389端口,其他还有ldaps://(端口636) or ldapi://
例如-h "ldaps:// ldap://127.0.0.1:666",开启了两个监听器,一个是636端口的基于LDAP/SSL 协议的监听器,
另一个是666端口的基于TCP协议的,仅可以在localhost地址上进行监听的监听器。
-n <service-name></service-name>定义服务名,默认是slapd
-l <syslog-local-user></syslog-local-user>设置写syslog日志的用户,可以是LOCAL0, LOCAL1, LOCAL2, ..., and LOCAL7. 默认是LOCAL4
-u user -g group 以什么用户,或用户组来运行slapd
-r directory 运行时的目录,slapd会chroot到该目录下。这是在打开所有监听器之后,但在读各种配置文件以及初始化后台服务之前进行的。
-d <level></level>| ? debug级别,各个级别的定义和1.1.5 loglevel相同的。可以同时打开多个级别的debug,可以用相加的方式,也可以不加。
如想:同时打开1和64两个级别,可以写-d 65,也可以写-d 1 -d 64.
如果要检查服务是否已经启动,并且是配置正确的,可以用:
ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
如:
ldapsearch -x -b 'dc=ldap,dc=com'可以查出相关记录
3.停止slapd
kill -INT `cat /usr/local/var/slapd.pid`
4.数据库操作
查询数据 ldapsearch
插入数据 ldapadd
ldapadd需要LDIF格式的数据导入文件。
例如一个文件example.ldif文件内容:
dn: dc=<my-domain></my-domain>,dc=<com></com>
objectclass: dcObject
objectclass: organization
o: <my organization=""></my>
dc: <my-domain></my-domain>
dn: cn=Manager,dc=<my-domain></my-domain>,dc=<com></com>
objectclass: organizationalRole
cn: Manager
然后执行命令:ldapadd -x -D "cn=Manager,dc=<my-domain></my-domain>,dc=<com></com>" -W -f example.ldif。
文件中的数据就被导入了。
修改数据 ldapmodify -x -D "cn=root,dc=it,dc=com" -W -f modify.ldif
-x表示用简单验证 -D表示指定目录 -W 表示弹出密码输入提示
重新创建索引 slapindex -f <slapdconfigfile></slapdconfigfile>
[-d <debuglevel></debuglevel>] [-n <databasenumber></databasenumber>|-b <suffix></suffix>]
导出数据 slapcat -l <filename></filename>-f <slapdconfigfile></slapdconfigfile>
[-d <debuglevel></debuglevel>] [-n <databasenumber></databasenumber>|-b <suffix></suffix>]
设置使用者密码 ldappasswd -x -D "cn=root,dc=it,dc=com" -W "uid=qq1,dc=it,dc=com" -S
5.schema介绍
schema类似数据库表结构定义,schema中的元素包含:
OID Assignment
------------------------------
1.1 Organization's OID
1.1.1 SNMP Elements
1.1.2 LDAP Elements
1.1.2.1 AttributeTypes
1.1.2.1.1 myAttribute
1.1.2.2 ObjectClasses
1.1.2.2.1 myObjectClass
5.1 AttributeTypes <rfc2252 description="" type="" attribute=""></rfc2252>
AttributeTypes相当于数据库中的表的属性,与数据库不同的是,一条记录,的一个属性可以有多个值。
attributetype语法是:
AttributeTypeDescription = "(" whsp
numericoid whsp ; AttributeType identifier
[ "NAME" qdescrs ] ; name used in AttributeType
[ "DESC" qdstring ] ; description
[ "OBSOLETE" whsp ]
[ "SUP" woid ] ; derived from this other
; AttributeType,如果没有SUP top
[ "EQUALITY" woid ; Matching Rule name
[ "ORDERING" woid ; Matching Rule name
[ "SUBSTR" woid ] ; Matching Rule name
[ "SYNTAX" whsp noidlen whsp ] ; Syntax OID
[ "SINGLE-VALUE" whsp ] ; default multi-valued
[ "COLLECTIVE" whsp ] ; default not collective
[ "NO-USER-MODIFICATION" whsp ]; default user modifiable
[ "USAGE" whsp AttributeUsage ]; default userApplications
whsp ")"
例子:
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 )
5.2 objectclass <rfc2252 class="" description="" object=""></rfc2252>
objectclass相当于数据库中的表,实际是目录,目录中的元素的属性在这里进行了定义。但重要的是目录与目录间的关系是没有定义的,
层次关系是在插入数据时的dn定义的。对不同的数据,目录的关系可以不同,这样是非常灵活的。
ObjectClassDescription = "(" whsp
numericoid whsp ; ObjectClass identifier
[ "NAME" qdescrs ]
[ "DESC" qdstring ]
[ "OBSOLETE" whsp ]
[ "SUP" oids ] ; Superior ObjectClasses
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
; default structural
[ "MUST" oids ] ; AttributeTypes
[ "MAY" oids ] ; AttributeTypes
whsp ")"
5.3
DN相当于数据库中的PK(Primary Key)
cn=Manager,dc=ldap,dc=com
6.JLDAP开发介绍
LDAPConnection ldapConn = new LDAPConnection();
ldapConn.connect(ldapHost, port);
ldapConn.bind(ldapVersion, loginDN, password.getBytes("UTF8"));
ldapConn.disconnect();
常用方法:
查询:ldapConn.search(searchBase,searchScope, searchFilter, attrs, attributeOnly);
修改:ldapConn.modify(dn, modSet.toArray(new LDAPModification[modSet.size()]));
删除:ldapConn.delete(deleteDN);
增加:ldapConn.add(new LDAPEntry(dn, attributeSet);