All Downloads are FREE. Search and download functionalities are using the official Maven repository.

base.ldap.LdapHelper Maven / Gradle / Ivy

/**
 * Creative commons Attribution-NonCommercial license.
 *
 * http://creativecommons.org/licenses/by-nc/2.5/au/deed.en_GB
 *
 * NO WARRANTY IS GIVEN OR IMPLIED, USE AT YOUR OWN RISK.
 */
package base.ldap;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;


/**
 * Manages connecting to an LDAP server and executing
 * basic LDAP commands.
 *
 * Querying the OID LDAP server:
 * 
 * LdapHelper ldap = new LdapHelper("ldap://sso-dev.portal.unimelb.edu.au:9327/", "cn=orcladmin,cn=Users,c=portal,o=unimelb,dc=edu,dc=au", "password");
 * for(String item : ldap.find("ou=people,o=unimelb", "(&(objectclass=person)(uid=gmtest*))"))
 *     System.out.println(" - " + item);
 * 
* * Querying the Centaur LDAP server: * *
 * LdapHelper ldap = new LdapHelper("ldaps://centaur.unimelb.edu.au:636/", "uid=username,ou=people,o=unimelb", "password", true);
 * for(String item : ldap.find("ou=people,o=unimelb", "(&(objectclass=person)(uid=gmtest*))"))
 *     System.out.println(" - " + item);
 * 
* */ public class LdapHelper { private DirContext ctx; /** * Initialise an LdapHelper wrapper to a specific LDAP server * * @param url JDBC url, ie ldaps://servername.com:689 * @param username LDAP username * @param password LDAP password * @param trusting When true, SSL certificate validation should be bypassed. */ public LdapHelper(String url, String username, String password, boolean trusting) throws NamingException { Hashtable env = new Hashtable<>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, url); env.put(Context.SECURITY_PRINCIPAL, username); env.put(Context.SECURITY_CREDENTIALS, password); if(trusting) { env.put("java.naming.ldap.factory.socket", "base.ssl.TrustingSslSocketFactory"); } ctx = new InitialDirContext(env); } /** * This method has been renamed, see getChildren() * * @param dn * @return * @throws IOException * @deprecated Deprecated in favour of getChildren() * @see getChildren() */ @Deprecated public List list(String dn) throws IOException { return getChildren(dn); } /** * Fetch the set of LDAP object sitting below this object in the ldap tree. * * @param dn Full dn of the parent object * @return List of full dn strings for each child object * @throws IOException */ public List getChildren(String dn) throws IOException { List names = new ArrayList<>(); NamingEnumeration items; try { items = ctx.list(dn); while(items.hasMore()) { NameClassPair item = items.next(); names.add(item.getName()); } } catch (NamingException e) { throw new IOException(e); } return names; } public Map getAttributes(String dn) throws IOException { Map attributes = new Hashtable<>(); try { Attributes result = ctx.getAttributes(dn); NamingEnumeration items = result.getAll(); while(items.hasMore()) { Attribute item = (Attribute)items.next(); if(item.size() > 0) { String c = attributes.get(item.getID()); for(int i = 0; i < item.size(); i++) { if(c == null) { c = ""; } if(c.length() > 0) { c = c + "|"; } try { c = c + (String)item.get(i); } catch(java.lang.ClassCastException e) { Logger.getLogger(LdapHelper.class.getName()).log(Level.WARNING, "Ignoring LDAP attribute that cant be cast to String: " + item.getID(), e); } } attributes.put(item.getID(), c); } else { if(item.get() instanceof String) { attributes.put(item.getID(), (String)item.get()); } } } } catch (NamingException e) { throw new IOException(e); } return attributes; } /** * Check if a DN exists on the ldap server. * * @param dn Unique DN to check * @return True if DN exists * @throws IOException */ public boolean exists(String dn) throws IOException { try { ctx.lookup(dn); return true; } catch (javax.naming.NameNotFoundException e) { return false; } catch (NamingException e) { throw new IOException(e); } } /** * Find the full unique DN of a person, where the username matches the cn field. * @param base DN containing the people we wish to search * @param username The value of the persons 'cn' attribute * @return Unique DN of this person, or null if not found. * @throws IOException */ public String findPersonDN(String base, String username) throws IOException { try { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration answer = ctx.search(base, "(&(objectclass=person)(cn="+username+"))", ctls); if (answer.hasMore()) { SearchResult sr = (SearchResult)answer.next(); answer.close(); return sr.getNameInNamespace(); } answer.close(); } catch(javax.naming.PartialResultException e) { System.out.println("Warning: "+e.getMessage()); } catch (NamingException e) { throw new IOException(e); } return null; } public String getGroupDN(String base, String group) throws IOException { try { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration answer = ctx.search(base, "(&(objectclass=group)(cn=*"+group+"*))", ctls); if (answer.hasMore()) { SearchResult sr = (SearchResult)answer.next(); answer.close(); return sr.getNameInNamespace(); } answer.close(); } catch(javax.naming.PartialResultException e) { System.out.println("Warning: "+e.getMessage()); } catch (NamingException e) { throw new IOException(e); } return null; } /** * Search the entire LDAP server using a filter * * @param filter The search filter * @return List of dn strings for each object that matches the filter * @throws IOException */ public List find(String filter) throws IOException { List names = new ArrayList(); try { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration answer = ctx.search("", filter, ctls); while (answer.hasMore()) { SearchResult sr = (SearchResult)answer.next(); names.add(sr.getNameInNamespace()); } answer.close(); } catch (NamingException e) { throw new IOException(e); } return names; } /** * Search the entire LDAP server using a filter * * @param baseDn The do a subtree search starting from this location * @param filter The search filter * @return List of dn strings for each object that matches the filter * @throws IOException */ public List find(String baseDn, String filter) throws IOException { List names = new ArrayList(); try { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration answer = ctx.search(baseDn, filter, ctls); while (answer.hasMore()) { SearchResult sr = (SearchResult)answer.next(); names.add(sr.getNameInNamespace()); } answer.close(); } catch (NamingException e) { throw new IOException(e); } return names; } public void add(String dn, String schemas, Map attributes) throws IOException { Attributes newAttributes = new BasicAttributes(true); Attribute oc = new BasicAttribute("objectclass"); for(String oclass : schemas.split(",")) { oc.add(oclass); } newAttributes.put(oc); for(String attribute : attributes.keySet()) { newAttributes.put(new BasicAttribute(attribute, attributes.get(attribute))); } try { ctx.createSubcontext(dn, newAttributes); } catch (NamingException e) { throw new IOException(e); } } /** * Remove an entry from the LDAP server, including all associated attributes and * children objects * * @param dn The DN of the object being removed. * @throws IOException */ public void delete(String dn) throws IOException { try { ctx.destroySubcontext(dn); } catch (NamingException e) { throw new IOException(e); } } public void addMemberToGroup(String userDn, String groupDn) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute("member", userDn); mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, mod0); try { ctx.modifyAttributes(groupDn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } public void removeMemberFromGroup(String userDn, String groupDn) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute("member", userDn); mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod0); try { ctx.modifyAttributes(groupDn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } /** * Depreciated in favour of using the more generic getMultivalueAttribute() call. Use * the following instead: * *
	 * ldap.getMultivalueAttribute(dn, "member");
	 * 
* * @param dn * @return * @throws IOException * @deprecated Deprecated in favour of using ldap.getMultivalueAttribute(dn, "member") */ @Deprecated public List getGroupMembers(String dn) throws IOException { return getMultivalueAttribute(dn, "member"); } public List getMultivalueAttribute(String dn, String attribute) throws IOException { List members = new ArrayList(); try { Attributes result = ctx.getAttributes(dn); NamingEnumeration items = result.getAll(); while(items.hasMore()) { Attribute item = (Attribute)items.next(); if(item.getID().equalsIgnoreCase(attribute)) { for(int i = 0; i < item.size(); i++) { members.add((String)item.get(i)); } } } } catch (NamingException e) { throw new IOException(e); } return members; } public List getPersonMembership(String dn) throws IOException { List members = new ArrayList(); try { Attributes result = ctx.getAttributes(dn); NamingEnumeration items = result.getAll(); while(items.hasMore()) { Attribute item = (Attribute)items.next(); if(item.getID().equalsIgnoreCase("memberOf")) { for(int i = 0; i < item.size(); i++) { members.add((String)item.get(i)); } } } } catch (NamingException e) { throw new IOException(e); } return members; } public void modifyAttribute(String dn, String attribute, String value) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute(attribute, value); mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0); try { ctx.modifyAttributes(dn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } public void addAttribute(String dn, String attribute, String value) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute(attribute, value); mods[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, mod0); try { ctx.modifyAttributes(dn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } public void removeAttribute(String dn, String attribute) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute(attribute, null); mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod0); try { ctx.modifyAttributes(dn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } /** * Remove an individual value from a multi-value attribute. * * @param dn * @param attribute * @param value * @throws IOException */ public void removeAttribute(String dn, String attribute, String value) throws IOException { ModificationItem[] mods = new ModificationItem[1]; Attribute mod0 = new BasicAttribute(attribute, value); mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, mod0); try { ctx.modifyAttributes(dn, mods); } catch (javax.naming.NameAlreadyBoundException e) { throw new IOException(e); } catch (NamingException e) { throw new IOException(e); } } public static String ldapEscape(String escape) { escape = escape.replaceAll("\\\\", "\\\\\\\\"); escape = escape.replaceAll(",", "\\\\,"); escape = escape.replaceAll("#", "\\\\#"); escape = escape.replaceAll("\\+", "\\\\+"); escape = escape.replaceAll("<", "\\\\<"); escape = escape.replaceAll(">", "\\\\>"); escape = escape.replaceAll(";", "\\\\;"); escape = escape.replaceAll("=", "\\\\="); return escape; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy