package org.ovirt.engine.core.bll.adbroker; import java.net.URI; import java.util.HashMap; import java.util.Map; import javax.naming.directory.SearchControls; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.springframework.ldap.control.PagedResultsCookie; import org.springframework.ldap.control.PagedResultsDirContextProcessor; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.NameClassPairCallbackHandler; import org.springframework.ldap.core.support.DirContextAuthenticationStrategy; import org.springframework.ldap.core.support.LdapContextSource; import org.springframework.ldap.core.support.SingleContextSource; public abstract class LDAPTemplateWrapper { private static LogCompat log = LogFactoryCompat.getLog(LDAPTemplateWrapper.class); protected LdapTemplate ldapTemplate; protected LdapContextSource contextSource; protected String password; protected String userName; protected DirContextAuthenticationStrategy authStrategy; protected String baseDN; protected String domain; protected boolean explicitAuth; public abstract void search(String baseDN, String filter, String displayFilter, SearchControls searchControls, NameClassPairCallbackHandler handler); public LDAPTemplateWrapper(LdapContextSource contextSource, String userName, String password, String domain) { this.contextSource = contextSource; ldapTemplate = new LdapTemplate(this.contextSource); this.userName = userName; this.password = password; this.domain = domain; this.baseDN = ""; } public void init(URI ldapURI, boolean setBaseDN, boolean explicitAuth, String explicitBaseDN, LdapProviderType ldapProviderType, long timeout) { this.explicitAuth = explicitAuth; if (explicitBaseDN != null) { this.baseDN = explicitBaseDN; } else if (!domain.isEmpty() && setBaseDN) { this.baseDN = getBaseDNForDomain(domain); } adjustUserName(ldapProviderType); this.contextSource.setUrl(ldapURI.toString()); setCredentialsOnContext(); contextSource.setBase(baseDN); contextSource.setContextFactory(com.sun.jndi.ldap.LdapCtxFactory.class); // binary properties Map<String, String> baseEnvironmentProperties = new HashMap<String, String>(); // objectGUID baseEnvironmentProperties.put("java.naming.ldap.attributes.binary", "objectGUID"); baseEnvironmentProperties.put("com.sun.jndi.ldap.connect.timeout", Long.toString(timeout)); contextSource.setBaseEnvironmentProperties(baseEnvironmentProperties); } protected abstract void setCredentialsOnContext(); public abstract void adjustUserName(LdapProviderType ldapProviderType); public void setIgnorePartialResultException(boolean value) { ldapTemplate.setIgnorePartialResultException(value); } public void useAuthenticationStrategy() throws EngineDirectoryServiceException { authStrategy = buildContextAuthenticationStategy(); contextSource.setAuthenticationStrategy(authStrategy); } protected abstract DirContextAuthenticationStrategy buildContextAuthenticationStategy(); private String getBaseDNForDomain(String domainName) { if (domainName == null) { return null; } Domain domain = UsersDomainsCacheManagerService.getInstance().getDomain(domainName); if (domain == null) { log.errorFormat("The domain {0} does not exist in the configuration. A base DN cannot be configured for it", domainName); return null; } synchronized (domain) { RootDSE rootDSE = domain.getRootDSE(); if (rootDSE != null) { return rootDSE.getDefaultNamingContext(); } } return null; } public void setExplicitAuth(boolean explicitAuth) { this.explicitAuth = explicitAuth; } protected NameClassPairCallbackHandler pagedSearch(String baseDN, String filter, String displayFilter, SearchControls searchControls, NameClassPairCallbackHandler handler) { /* * once a SingleContextSource is constructed, it must be destroyed (see below), otherwise only the garbage * collector will close its connection. */ final SingleContextSource singleContextSource = new SingleContextSource(contextSource.getContext(userName, password)); try { ldapTemplate.setContextSource(singleContextSource); if (log.isDebugEnabled()) { log.debugFormat("LDAP query is {0}", displayFilter); } int ldapPageSize = Config.<Integer> GetValue(ConfigValues.LdapQueryPageSize); PagedResultsDirContextProcessor requestControl = new PagedResultsDirContextProcessor(ldapPageSize); ldapTemplate.search(baseDN, filter, searchControls, handler, requestControl); PagedResultsCookie cookie = requestControl.getCookie(); while (cookie != null) { byte[] cookieBytes = cookie.getCookie(); if (cookieBytes == null) { break; } requestControl = new PagedResultsDirContextProcessor(ldapPageSize, cookie); ldapTemplate.search(baseDN, filter, searchControls, handler, requestControl); cookie = requestControl.getCookie(); } } catch (Exception ex) { log.errorFormat("Error in running LDAP query. BaseDN is {0}, filter is {1}. Exception message is: {2}", baseDN, displayFilter, ex.getMessage()); handleException(ex); } finally { singleContextSource.destroy(); } return handler; } /** * @param ex */ private Throwable handleException(Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } return e; } }