OpenLdap安装与测试
????? OpenLDAP是轻型目录访问协议(Lightweight Directory Access Protocol,LDAP)的自由和开源的实现,在其OpenLDAP许可证下发行,并已经被包含在众多流行的Linux发行版中。
它主要包括下述4个部分:
slapd - 独立LDAP守护服务
slurpd - 独立的LDAP更新复制守护服务
实现LDAP协议的库
工具软件和示例客户端
- 下载openldap-2.2.29-db-4.3.29-openssl-0.9.8a-win32_Setup.exe(下面所有的操作均以该版本为基础)双击傻瓜式安装(安装过程中用户可以选择是否将OpenLDAP-slurpd和OpenLDAP-slapd配置成计算机的服务,随用户计算机的启动而启动,默认情况下OpenLDAP-slurpd不会被安装成系统服务)安装完成后的目录结构为:(我的安装位置为C:\OpenLDAP) 目录功能datacontains all the DBD (database) filesdocsdocumentationrunvarious run time files (.pid and .args)schemastandard openldap schema filesucdataunicode data用户可以通过cmmand line(cmd)的services.msc来查看或启动OpenLdap服务,若启动服务失败用户需查看错误日志或查看服务端口
?? netstat -an
# this will list all the active ports and their
# status. Confirm that port 389 is active.配置 openldap,编辑 sldap.conf 文件
1) 打开C:\OpenLDAP\sldap.conf,找到
????? include include??? ??? ./schema/core.schema
????? 在它后面添加
include ./schema/cosine.schema
include ./ schema/inetorgperson.schema
接下来的例子只需要用到以上三个 schema,当然,如果你觉得需要的话,你可以把其他的 schema 全部添加进来
include ./schema/corba.schema
include ./schema/dyngroup.schema
include ./schema/java.schema
include ./schema/misc.schema
include ./schema/nis.schema
????? include ./schema/openldap.schema
??? 2) 还是在 sldap.conf 文件中,找到?
suffix "dc=example,dc=com"
rootdn "cn=Manager,dc= example,dc=com"
把这两行改为
suffix "dc=lcl,c=com"
rootdn "cn=admin,dc=lcl,dc=com"
????? suffix 根据自己情况定义。
????? 还要注意到这个配置文件中有一个 rootpw secret,这个 secret 是 cn=Manager 的密码,以后会用到,不过这里是明文密码,你可以用命令:
slappasswd -h {md5} -s secret
????? 算出加密的密码 {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ== 取代配置中的 secret。
????3) 启动 openldap (我安装时安装为自启动方式,用户可以根据情况配置)
CMD 进入到C:\OpenLDAP 下,运行命令 slapd -d 1
????? 用可以看到控制台下打印一片信息,openldap 默认是用的 Berkeley DB 数据库存储目录数据的。
??? 4)配置后的sldap.conf如下所示:
????? #
????? ##########################################
????? # 加载哪些 schemas 文件
????? #
????? ucdata-path??? ./ucdata
??????include??? ??? ./schema/core.schema
????? include??? ??? ./schema/cosine.schema
????? include??? ??? ./schema/inetorgperson.schema
????? #########################################
????? # 下面这些都是默认的配置
??????pidfile??? ??? ./run/slapd.pid
????? argsfile??? ./run/slapd.args
????? #######################################################################
????? # BDB database definitions
????? #######################################################################
????? database??? bdb
????? # 这个是我们需要配置的。
????? suffix??? ??? "dc=lcl,dc=com"
????? # 设置LDAP的超级用户密码,用户名admin,密码user@XX2
????? rootdn??? ??? "cn=admin,dc=lcl,dc=com"
????? # Use of strong authentication encouraged.
????? rootpw??? ??? 1234abcd@
????? # The database directory MUST exist prior to running slapd AND
????? # should only be accessible by the slapd and slap tools.
????? # LDAP数据保存的路径
????? directory??? ./data
????? #########################################
????? # 下面这些都是默认的配置
????? # Indices to maintain
????? .................................配置LDAP的数据文件example.ldif
objectClass以及attribute等信息都是在schema中定义的。在默认的情况下 OpenLdap会在slap.conf中包含必须的schema(core.schema)。在schema中定义的时候,对于objectClass 以及attribute都会根据规范来进行定义相关的约束。经常使用的schema在网络上都可以找到,不用自己来定义,毕竟定义一个schema不是一 件容易的事情。
在我们向Ldap中添加Entry的时候,我们将用到schema中定义的相关项。如:我们的Entry需要使用objectClass,在 objectClass中使用attribute。在使用objectClass(一个或者多个)创建一个Entry的时候,需要至少一个 objectClass的类型为STRUCTURAL类型的,否则将不能够添加到LdapServer中,当然在添加一个Entry的时候,有一些属性是必须的,而有一些属性是可选的。对于必须的属性,在创建的时候,需要给定具体的值。## 定义DIT(directory information tree 目录信息树)的 ROOT/BASE/SUFFIX###### replace example and com as necessary below## or for experimentation leave as is## dcObject is an AUXILLIARY objectclass and MUST## have a STRUCTURAL objectclass (organization in this case)# this is an ENTRY sequence and is preceded by a BLANK linedn: dc=lcl,dc=comdc: lcldescription: test lcl descriptionobjectClass: dcObjectobjectClass: organizationo: lcl, Inc.## FIRST Level hierarchy users ## uses mixed upper and lower case for objectclass# this is an ENTRY sequence and is preceded by a BLANK linedn: ou=users, dc=lcl,dc=comou: usersdescription: All users in organisationobjectclass: organizationalunit## SECOND Level hierarchy## ADD a single entry under FIRST (people) level# this is an ENTRY sequence and is preceded by a BLANK line# the ou: Human Resources is the department namedn: cn=Robert Smith,ou=users,dc=lcl,dc=comobjectclass: inetOrgPersoncn: Robert Smithcn: Robert J Smithcn: bob smithsn: smithuid: rjsmithuserpassword: rJsmitHcarlicense: HISCAR 123homephone: 555-111-2222mail: r.smith@example.commail: rsmith@example.commail: bob.smith@example.comdescription: swell guyou: Human Resources?
通过命令C:\OpenLDAP>ldapadd.exe -x -D "cn=admin,dc=lcl,dc=com" -f e:\step-1.ldif -w 1234abcd@导入ldif中的数据
adding new entry "dc=lcl,dc=com"
adding new entry "ou=users, dc=lcl,dc=com"
adding new entry "cn=Robert Smith,ou=users,dc=lcl,dc=com"通过java访问openldappackage test;import java.util.Hashtable;import javax.naming.Context;import javax.naming.NamingEnumeration;import javax.naming.NamingException;import javax.naming.directory.DirContext;import javax.naming.directory.InitialDirContext;import javax.naming.directory.SearchControls;import javax.naming.directory.SearchResult;public class TestJndiLdapSearch { public static void main(String[] args) { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=lcl,dc=com"); env.put(Context.SECURITY_CREDENTIALS, "1234abcd@"); String root = "dc=lcl,dc=com"; try { DirContext context = new InitialDirContext(env); // 使用方式见jdk1.6的InitialDirContext的search // Specify the ids of the attributes to return String[] attrIDs = { "sn", "telephonenumber", "name", "mail" }; // Create the default search controls SearchControls ctls = new SearchControls(); ctls.setReturningAttributes(attrIDs); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); String filter = "(&(cn=*))"; // Search for objects that have those matching attributes NamingEnumeration enum = context.search(root, filter, ctls); while (enum.hasMore()) { SearchResult result = (SearchResult) enum.next(); System.out.println("name : " + result.getName()); } } catch (NamingException e) { e.printStackTrace(); } }}?
?