LDAP基本操作

本文基于OpenLDAP来演示常见的LDAP操作,包括新增、修改、查询等。

安装OpenLDAP

以Ubuntu为例,

# Run as root
$ sudo apt install slapd ldap-utils

安装过程中会提示设置OpenLDAP的管理员密码。安装过程中会以 本机域名 为基础创建一个目录信息库,前面提示设置的密码为该目录信息库的密码。我的试验安装机器的域名是027yunwei.com, 则目录信息库的后缀为:

dc=027yunwei,dc=com

默认产生的管理员账号为:

cn=admin,dc=027yunwei,dc=com

安装完毕以后,OpenLDAP服务进程就已经启动了。

# Run as root
$ sudo service slapd status
* slapd is running

安装创建的目录信息库(dc=027yunwei,dc=com)中现在有两个条目, 可以查询到

$ sudo ldapsearch -Y EXTERNAL -H ldapi:// -b dc=027yunwei,dc=com -LLL
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: dc=027yunwei,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: 027yunwei.com
dc: 027yunwei

dn: cn=admin,dc=027yunwei,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

添加样例数据

在本例中,我们增加一个表示人员的组织单元,然后再添加二个人员。 Linux上可以使用命令行工具ldapadd来添加:

ldapadd -x -H ldapi:/// -D cn=admin,dc=027yunwei,dc=com  -W  -c -f add-users.ldif

上述运行时会提示输入密码。请输入前面安装时设置的密码即可。 其中,

  1. -x 表示使用简单密码验证
  2. -H ldapi:/// 表示通过ldapi协议连接本地LDAP服务
  3. -D cn=admin,dc=027yunwei,dc=com 表示验证的用户是admin
  4. -W 表示会提示输入密码
  5. -c 表示如果批量执行中出错后仍然继续处理余下条目
  6. -f add-users.ldif 表示从文件add-users.ldif中读取信息条目

上述命令中的用户文件 add-users.ldif内容如下:

dn: ou=people,dc=027yunwei,dc=com
objectclass: organizationalUnit
ou: people

dn: cn=wanggan,ou=people,dc=027yunwei,dc=com
cn: wanggan
objectclass: inetOrgPerson
sn: Wang
mail: 407648477@qq.com
# Changeme
userPassword: {SSHA}nxCY1k+FwiuTg5nCefNagEM+sZV5OaFp

dn: cn=user1,ou=people,dc=027yunwei,dc=com
cn: user1
objectclass: inetOrgPerson
sn: User1
mail: user1@gmail.com
# Hi.2016.Aug
userPassword: {SSHA}X6GslGMiU5NWsk8nV5ExBANIozd3Qhzh

上述文件内容中的userPassword密码是散列函数混淆后的结果,其上方的注释内容是明文。可以通过slappasswd来生成:

slappasswd

上述命令执行时,会提示输入密码,然后就会生成加密后的结果。

至此我们的LDAP信息库中就多出了这两个用户: wanggan, user1。

用户身份验证

LDAP的一个典型用途是身份验证。类似于登录验证,输入用户名和密码,校验是否匹配。 比如上面添加的用户wanggan,可以通过ldapwhoami来验证:

ldapwhoami -x -H ldapi:/// -D cn=wanggan,ou=people,dc=027yunwei,dc=com -W
Enter LDAP Password:
dn:cn=wanggan,ou=people,dc=027yunwei,dc=com

如果输入错误的密码,结果是:

ldapwhoami -x -H ldapi:/// -D cn=wanggan,ou=people,dc=027yunwei,dc=com -W
Enter LDAP Password:
ldap_bind: Invalid credentials (49)

查询用户

以几种常见的查询来演示查询。

按邮箱查询

下面的命令是查询邮箱为user1@gmail.com的用户信息:

ldapsearch -x -H ldapi:/// -D cn=wanggan,ou=people,dc=027yunwei,dc=com -W -b dc=027yunwei,dc=com  '(mail=user1@gmail.com)'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=027yunwei,dc=com> with scope subtree
# filter: (mail=user1@gmail.com)
# requesting: ALL
#

# user1, people, 027yunwei.com
dn: cn=user1,ou=people,dc=027yunwei,dc=com
cn: user1
objectClass: inetOrgPerson
sn: User1
mail: user1@gmail.com

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

上面命令的输出结果中,以#开头的是对结果部分的解释说明。

按邮箱或用户名称查询

下面的例子是按用户名user1或者邮箱user1@gmail.com来查询,

ldapsearch -x -H ldapi:/// -D cn=wanggan,ou=people,dc=027yunwei,dc=com -W -b dc=027yunwei,dc=com  '(|(mail=user1@gmail.com) (cn=user1))'
Enter LDAP Password:
# extended LDIF
#
# LDAPv3
# base <dc=027yunwei,dc=com> with scope subtree
# filter: (|(mail=user1@gmail.com) (cn=user1))
# requesting: ALL
#

# user1, people, 027yunwei.com
dn: cn=user1,ou=people,dc=027yunwei,dc=com
cn: user1
objectClass: inetOrgPerson
sn: User1
mail: user1@gmail.com

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

要注意本例中的查询过滤条件的写法。LDAP查询条件的基本构成是:

( attribute op value )

即写在小括号内的属性与值的匹配。 如果有多个条件需要过滤,则使用“与或”逻辑。与逻辑,表示多个条件都需要满足, 其符号为 "&", 或逻辑,表示多个条件满足其中某个即可,其符号为 "|"。

( & (attribute1 op1 value1) (attribute2 op2 value2) (...) )
( | (attribute1 op1 value1) (attribute2 op2 value2) (...) )

参考资料

  1. 联机手册 man ldapsearch; man ldapadd; man ldif
  2. LDAP查询过滤表达式 RFC 2254