1、http:/njcJAVA,OpenLDAP使用心得如何安装已经在官方文档有了,一步步的照着做就可以/usr/local/etc/openldap/slapd.conf中可以找到schema,pid以及数据库文件存放的路径我修改了/usr/local/etc/openldap/slapd.conf文件,但是发现没啥用,原来是忘了把slapd停止重新启动了。关于停止slapd,官方给的是:kill -INT cat /usr/local/var/slapd.pid但是我执行以后提示bash: kill: cat /usr/local/var/slapd.pid: arguments must b
2、e process or job IDs用find /usr -name slapd.pid命令找到了在/usr/local/var/run/下,把命令改为:kill -INT cat /usr/local/var/run/slapd.pid重新运行slapd:su root -c /usr/local/libexec/slapd建议执行/usr/local/libexec/slapd -d256 命令,这样既可以在命令行看到出错信息,也可以用Ctrl+C停止进程关于rootpw,很多地方都说rootpw和密码值之间不能加空格,不然会出错。有个解决的办法:rootpw secret 加了双引号
3、,只要输入的密码和引号里面的对应就可以了。很多人在测试ldapadd命令时,都遇到过ldap_bind: Invalid credentials(49)错误,看看rootdn cn=Manager,dc=example,dc=com和自己的ldif里面的dn参数是不是匹配,如果不匹配就需要修改,修改后记得要停止重启哦(我还不知道怎么重新读取配置的方法,只能用这种笨方法了)折腾了一天,终于初步了解JAVA怎么在OpenLDAP增加删除数据了。代码如下/* author chenyi*/import java.util.Hashtable;import javax.naming.Context;i
4、mport javax.naming.NamingException;import javax.naming.directory.*;import java.util.*;public class ChenYi DirContext ctx = null; String account = Manager;/操作LDAP的帐户。默认就是Manager。 String password = secret;/帐户Manager的密码。 String root = dc=example,dc=com; /LDAP的根节点的DC public ChenYi() init(); add(); /dele
5、te(); close(); public void init() Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.ldap.LdapCtxFactory);env.put(Context.PROVIDER_URL, ldap:/192.168.100.221:389/); env.put(Context.SECURITY_AUTHENTICATION, simple); env.put(Context.SECURITY_PRINCIPAL, cn= + account
6、 + , + root); env.put(Context.SECURITY_CREDENTIALS, password); try ctx = new InitialDirContext(env);/初始化上下文 System.out.println(认证成功);/这里可以改成异常抛出。 catch (javax.naming.AuthenticationException e) System.out.println(认证失败); catch (Exception e) System.out.println(认证出错: + e); public void add() try String n
7、ewUserName = hi; BasicAttributes attrs = new BasicAttributes(); BasicAttribute objclassSet = new BasicAttribute(objectClass); objclassSet.add(top); objclassSet.add(organizationalUnit); attrs.put(objclassSet); attrs.put(ou, newUserName); ctx.createSubcontext(ou= + newUserName + , + root, attrs); catc
8、h (Exception e) e.printStackTrace(); System.out.println(Exception in add(): + e); public void delete() try ctx.destroySubcontext(ou=hi,dc=example,dc=com); catch (Exception e) e.printStackTrace(); System.out.println(Exception in delete(): + e); public void close() if (ctx != null) try ctx.close(); ca
9、tch (NamingException e) System.out.println(NamingException in close(): + e); public static void main(String args) new ChenYi(); 红线标记的地方特别注意,我看很多文章中写的都类似于env.put(Context.PROVIDER_URL, ldap:/localhost:7001/ + root); 经过我一天的折腾发现加上了root,会报javax.naming.NameNotFoundException: LDAP: error code 32 - No Such
10、Object;错误。也许这是新版不兼容旧版程序吧今天终于把添加,删除,修改节点名,属性,遍历节点都弄出来了,先把代码贴出来吧/* author chenyi*/import java.util.Hashtable;import javax.naming.directory.*;import java.util.*;import javax.naming.*;public class ChenYi DirContext dc = null; String account = Manager;/操作LDAP的帐户。默认就是Manager。 String password = secret;/帐户M
11、anager的密码。 String root = dc=example,dc=com; /LDAP的根节点的DC public ChenYi() init(); /add();/添加节点 /delete(ou=hi,dc=example,dc=com);/删除ou=hi,dc=example,dc=com节点 /modifyInformation(ou=hi,dc=example,dc=com);/修改ou=hi,dc=example,dc=com属性 /renameEntry(ou=new,o=neworganization,dc=example,dc=com,ou=neworganizat
12、ionalUnit,o=neworganization,dc=example,dc=com);/重命名节点ou=new,o=neworganization,dc=example,dc=com searchInformation(dc=example,dc=com, , (objectclass=*);/遍历所有根节点 /searchInformation(o=neworganization,dc=example,dc=com,(objectclass=*);/遍历指定节点的分节点 close(); public void init() Hashtable env = new Hashtable
13、(); env.put(Context.INITIAL_CONTEXT_FACTORY, com.sun.jndi.ldap.LdapCtxFactory); env.put(Context.PROVIDER_URL, ldap:/192.168.100.221:389/); env.put(Context.SECURITY_AUTHENTICATION, simple); env.put(Context.SECURITY_PRINCIPAL, cn= + account + , + root); env.put(Context.SECURITY_CREDENTIALS, password);
14、 try dc = new InitialDirContext(env);/初始化上下文 System.out.println(认证成功);/这里可以改成异常抛出。 catch (javax.naming.AuthenticationException e) System.out.println(认证失败); catch (Exception e) System.out.println(认证出错: + e); public void close() if (dc != null) try dc.close(); catch (NamingException e) System.out.prin
15、tln(NamingException in close(): + e); public void add() try String newUserName = hi; BasicAttributes attrs = new BasicAttributes(); BasicAttribute objclassSet = new BasicAttribute(objectClass); objclassSet.add(top); objclassSet.add(organizationalUnit); attrs.put(objclassSet); attrs.put(ou, newUserNa
16、me); dc.createSubcontext(ou= + newUserName + , + root, attrs); catch (Exception e) e.printStackTrace(); System.out.println(Exception in add(): + e); public void delete(String dn) try dc.destroySubcontext(dn); catch (Exception e) e.printStackTrace(); System.out.println(Exception in delete(): + e); pu
17、blic boolean modifyInformation(String dn) try ModificationItem mods = new ModificationItem1; /*添加属性*/ Attribute attr0 = new BasicAttribute(description,/ 测试);/ mods0 = new ModificationItem(DirContext.ADD_ATTRIBUTE,attr0);/*修改属性*/ Attribute attr0 = new BasicAttribute(description, 陈轶);/ mods0 = new Mod
18、ificationItem(DirContext.REPLACE_ATTRIBUTE,/ attr0); /*删除属性*/ Attribute attr0 = new BasicAttribute(description, 陈轶); mods0 = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr0); dc.modifyAttributes(dn, mods); return true; catch (NamingException ne) ne.printStackTrace(); System.err.println(Error
19、: + ne.getMessage(); return false; /* * param base :根节点(在这里是dc=example,dc=com) * param scope :搜索范围,分为base(本节点),one(单层),(遍历) * param filter :指定子节点(格式为(objectclass=*),*是指全部,你也可以指定某一特定类型的树节点) */ public void searchInformation(String base, String scope, String filter) SearchControls sc = new SearchContro
20、ls(); if (scope.equals(base) sc.setSearchScope(SearchControls.OBJECT_SCOPE); else if (scope.equals(one) sc.setSearchScope(SearchControls.ONELEVEL_SCOPE); else sc.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration ne = null; try ne = dc.search(base, filter, sc); / Use the NamingEnumerati
21、on object to cycle through / the result set. while (ne.hasMore() System.out.println(); SearchResult sr = (SearchResult) ne.next(); String name = sr.getName(); if (base != null & !base.equals() System.out.println(entry: + name + , + base); else System.out.println(entry: + name); Attributes at = sr.ge
22、tAttributes(); NamingEnumeration ane = at.getAll(); while (ane.hasMore() Attribute attr = (Attribute) ane.next(); String attrType = attr.getID(); NamingEnumeration values = attr.getAll(); Vector vals = new Vector(); / Another NamingEnumeration object, this time / to iterate through attribute values.
23、 while (values.hasMore() Object oneVal = values.nextElement(); if (oneVal instanceof String) System.out.println(attrType + : + (String) oneVal); else System.out.println(attrType + : + new String(byte) oneVal); catch (Exception nex) System.err.println(Error: + nex.getMessage(); nex.printStackTrace();
24、 public boolean renameEntry(String oldDN, String newDN) try dc.rename(oldDN, newDN); return true; catch (NamingException ne) System.err.println(Error: + ne.getMessage(); return false; public static void main(String args) new ChenYi(); 经过几天的努力,把获取objectClass定义和获取Attribute定义的代码弄出来,这样就方便了以后根据自定义schema动
25、态的获取schema中的objectClass和Attribute。特别是对于做添加修改界面应该有点用处,修改了schema并不需要修改代码做代码调整,只需要根据获取的属性个数挨个排好,让别人填入值,并且可以检测MUST的是不是已经填写了。 /* * 获取指定objectClass的定义 * param name */ public void getObjectClassDefinition(String name) try / Get the schema tree root DirContext schema = dc.getSchema(); / Get the schema objec
26、t for person DirContext personSchema = (DirContext) schema.lookup(ClassDefinition/ + name); Attributes a = personSchema.getAttributes(); NamingEnumeration ane = a.getAll(); while (ane.hasMore() Attribute attr = (Attribute) ane.next(); String attrType = attr.getID(); NamingEnumeration values = attr.g
27、etAll(); while (values.hasMore() Object oneVal = values.nextElement(); if (oneVal instanceof String) System.out.println(attrType + : + (String) oneVal); else System.out.println(attrType + : + new String(byte) oneVal); catch (Exception e) e.printStackTrace(); /* * 获取指定DN的objectClass定义 * param DN */ p
28、ublic void getDNObjectClassDefinition(String DN) try / Get context containing class definitions for the cn=Ted Geisel entry DirContext tedClasses = dc.getSchemaClassDefinition(DN); / Enumerate the class definitions NamingEnumeration enum1 = tedClasses.search(, null); while (enum1.hasMore() Object o
29、= enum1.next(); System.out.println(SearchResult) o).getName(); Attributes a = (SearchResult) o).getAttributes(); NamingEnumeration ane = a.getAll(); while (ane.hasMore() Attribute attr = (Attribute) ane.next(); String attrType = attr.getID(); NamingEnumeration values = attr.getAll(); while (values.h
30、asMore() Object oneVal = values.nextElement(); if (oneVal instanceof String) System.out.println(attrType + : + (String) oneVal); else System.out.println(attrType + : + new String(byte) oneVal); catch (Exception e) e.printStackTrace(); /* * 获取指定名字的Attribute定义 * param name */ public void getAttributeD
31、efinition(String name) try / Get the schema tree root DirContext schema = dc.getSchema(); / Get the schema object for person DirContext personSchema = (DirContext) schema.lookup(AttributeDefinition/ + name); Attributes a = personSchema.getAttributes(); NamingEnumeration ane = a.getAll(); while (ane.
32、hasMore() Attribute attr = (Attribute) ane.next(); String attrType = attr.getID(); NamingEnumeration values = attr.getAll(); while (values.hasMore() Object oneVal = values.nextElement(); if (oneVal instanceof String) System.out.println(attrType + : + (String) oneVal); else System.out.println(attrTyp
33、e + : + new String(byte) oneVal); catch (Exception e) e.printStackTrace(); /* * 获取指定DN中指定名字的Attribute定义 * param DN * param name */ public void getDNAttributeDefinition(String DN, String name) try / Get an attribute of that type Attributes attrs = dc.getAttributes(DN, new Stringname); Attribute cnAtt
34、r = attrs.get(name); / Get its attribute type definition DirContext cnSchema = cnAttr.getAttributeDefinition(); / Get cnSchemas attributes Attributes cnAttrs = cnSchema.getAttributes(); NamingEnumeration ane = cnAttrs.getAll(); while (ane.hasMore() Attribute attr = (Attribute) ane.next(); String attrType = attr.getID(); NamingEnumeration values = attr.ge