package io.cattle.platform.iaas.api.auth.integration.ldap.ad; import io.cattle.platform.iaas.api.auth.integration.ldap.ServiceContextCreationException; import io.cattle.platform.iaas.api.auth.integration.ldap.interfaces.LDAPConstants; import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapContext; import javax.naming.ldap.LdapName; import org.apache.commons.lang3.StringUtils; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectFactory; import org.apache.commons.pool2.impl.DefaultPooledObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LdapServiceContextPoolFactory implements PooledObjectFactory<LdapContext> { private static final Logger logger = LoggerFactory.getLogger(LdapServiceContextPoolFactory.class); LDAPConstants config; public LdapServiceContextPoolFactory(LDAPConstants config) { this.config = config; } @Override public PooledObject<LdapContext> makeObject() throws Exception { String username = config.getServiceAccountUsername(); if (StringUtils.isNotBlank(config.getLoginDomain()) && !username.contains("\\")) { username = config.getLoginDomain() + '\\' +username; } Hashtable<String, String> props = new Hashtable<>(); props.put(Context.SECURITY_AUTHENTICATION, "simple"); props.put(Context.SECURITY_PRINCIPAL, username); props.put(Context.SECURITY_CREDENTIALS, config.getServiceAccountPassword()); props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); props.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(config.getConnectionTimeout())); LdapContext userContext; try { String url = "ldap://" + config.getServer() + ':' + config.getPort() + '/'; props.put(Context.PROVIDER_URL, url); if (config.getTls()) { props.put(Context.SECURITY_PROTOCOL, "ssl"); } userContext = new InitialLdapContext(props, null); } catch (NamingException e) { logger.info("Failed to create a service context: {}", e.getMessage()); throw new ServiceContextCreationException("Unable to login to ldap using configured Service account.", e); } return new DefaultPooledObject<>(userContext); } @Override public void destroyObject(PooledObject<LdapContext> p) throws Exception { p.getObject().close(); } @Override public boolean validateObject(PooledObject<LdapContext> p) { try { p.getObject().getAttributes(new LdapName(config.getDomain())); return true; } catch (NamingException e) { logger.info("Failed to validate an existing ldap service context: {}", e.getMessage()); return false; } } @Override public void activateObject(PooledObject<LdapContext> p) throws Exception { } @Override public void passivateObject(PooledObject<LdapContext> p) throws Exception { } }