资源描述
http://njc JAVA,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 be 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" 加了双引号,只要输入的密码和引号里面的对应就可以了。
很多人在测试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;
import 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();
//delete();
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 + "," + 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 newUserName = "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);
} catch (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();
} catch (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 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";//帐户Manager的密码。
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=neworganizationalUnit,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();
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);
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.println("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", newUserName);
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);
}
}
public boolean modifyInformation(String dn) {
try {
ModificationItem[] mods = new ModificationItem[1];
/*添加属性*/
// Attribute attr0 = new BasicAttribute("description",
// "测试");
// mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE,attr0);
/*修改属性*/
// Attribute attr0 = new BasicAttribute("description", "陈轶");
// mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
// attr0);
/*删除属性*/
Attribute attr0 = new BasicAttribute("description",
"陈轶");
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
attr0);
dc.modifyAttributes(dn, mods);
return true;
} catch (NamingException ne) {
ne.printStackTrace();
System.err.println("Error: " + 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 SearchControls();
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 NamingEnumeration 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.getAttributes();
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.
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();
}
}
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动态的获取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 object 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.getAll();
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
*/
public 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 = 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.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();
}
}
/**
* 获取指定名字的Attribute定义
* @param name
*/
public void getAttributeDefinition(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.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(attrType + ": " + 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 String[]{name});
Attribute cnAttr = attrs.get(name);
// Get its attribute type definition
DirContext cnSchema = cnAttr.getAttributeDefinition();
// Get cnSchema's 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
展开阅读全文