in src/main/java/com/amazon/dlic/auth/ldap/backend/LDAPAuthorizationBackend.java [249:479]
private static Connection getConnection0(final Settings settings, final Path configPath, final ClassLoader cl,
final boolean needRestore) throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
FileNotFoundException, IOException, LdapException {
final boolean enableSSL = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL, false);
final List<String> ldapHosts = settings.getAsList(ConfigConstants.LDAP_HOSTS,
Collections.singletonList("localhost"));
Connection connection = null;
Exception lastException = null;
final boolean isDebugEnabled = log.isDebugEnabled();
final boolean isTraceEnabled = log.isTraceEnabled();
for (String ldapHost : ldapHosts) {
if (isTraceEnabled) {
log.trace("Connect to {}", ldapHost);
}
try {
final String[] split = ldapHost.split(":");
int port;
if (split.length > 1) {
port = Integer.parseInt(split[1]);
} else {
port = enableSSL ? 636 : 389;
}
final ConnectionConfig config = new ConnectionConfig();
config.setLdapUrl("ldap" + (enableSSL ? "s" : "") + "://" + split[0] + ":" + port);
if (isTraceEnabled) {
log.trace("Connect to {}", config.getLdapUrl());
}
configureSSL(config, settings, configPath);
final String bindDn = settings.get(ConfigConstants.LDAP_BIND_DN, null);
final String password = settings.get(ConfigConstants.LDAP_PASSWORD, null);
if (isDebugEnabled) {
log.debug("bindDn {}, password {}", bindDn,
password != null && password.length() > 0 ? "****" : "<not set>");
}
if (bindDn != null && (password == null || password.length() == 0)) {
log.error("No password given for bind_dn {}. Will try to authenticate anonymously to ldap", bindDn);
}
final boolean enableClientAuth = settings.getAsBoolean(ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH,
ConfigConstants.LDAPS_ENABLE_SSL_CLIENT_AUTH_DEFAULT);
if (isDebugEnabled) {
if (enableClientAuth && bindDn == null) {
log.debug("Will perform External SASL bind because client cert authentication is enabled");
} else if (bindDn == null) {
log.debug("Will perform anonymous bind because no bind dn is given");
} else if (enableClientAuth && bindDn != null) {
log.debug(
"Will perform simple bind with bind dn because to bind dn is given and overrides client cert authentication");
} else if (!enableClientAuth && bindDn != null) {
log.debug("Will perform simple bind with bind dn");
}
}
if (bindDn != null && password != null && password.length() > 0) {
config.setConnectionInitializer(new BindConnectionInitializer(bindDn, new Credential(password)));
} else if (enableClientAuth) {
SaslConfig saslConfig = new SaslConfig();
saslConfig.setMechanism(Mechanism.EXTERNAL);
BindConnectionInitializer bindConnectionInitializer = new BindConnectionInitializer();
bindConnectionInitializer.setBindSaslConfig(saslConfig);
config.setConnectionInitializer(bindConnectionInitializer);
} else {
// No authentication
}
DefaultConnectionFactory connFactory = new DefaultConnectionFactory(config);
connection = connFactory.getConnection();
connection.open();
if (connection != null && connection.isOpen()) {
break;
} else {
Utils.unbindAndCloseSilently(connection);
if (needRestore) {
restoreClassLoader0(cl);
}
connection = null;
}
} catch (final Exception e) {
lastException = e;
log.warn("Unable to connect to ldapserver {} due to {}. Try next.", ldapHost, e.toString());
Utils.unbindAndCloseSilently(connection);
if (needRestore) {
restoreClassLoader0(cl);
}
connection = null;
continue;
}
}
if (connection == null || !connection.isOpen()) {
Utils.unbindAndCloseSilently(connection); //just in case
if (needRestore) {
restoreClassLoader0(cl);
}
connection = null;
if (lastException == null) {
throw new LdapException("Unable to connect to any of those ldap servers " + ldapHosts);
} else {
throw new LdapException(
"Unable to connect to any of those ldap servers " + ldapHosts + " due to " + lastException,
lastException);
}
}
final Connection delegate = connection;
if (isDebugEnabled) {
log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet());
}
return new Connection() {
@Override
public Response<Void> reopen(BindRequest request) throws LdapException {
if (isDebugEnabled) {
log.debug("Reopened a connection");
}
return delegate.reopen(request);
}
@Override
public Response<Void> reopen() throws LdapException {
if (isDebugEnabled) {
log.debug("Reopened a connection");
}
return delegate.reopen();
}
@Override
public Response<Void> open(BindRequest request) throws LdapException {
try {
if(isDebugEnabled && delegate != null && delegate.isOpen()) {
log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet());
}
} catch (Throwable e) {
//ignore
}
return delegate.open(request);
}
@Override
public Response<Void> open() throws LdapException {
try {
if(isDebugEnabled && delegate != null && delegate.isOpen()) {
log.debug("Opened a connection, total count is now {}", CONNECTION_COUNTER.incrementAndGet());
}
} catch (Throwable e) {
//ignore
}
return delegate.open();
}
@Override
public boolean isOpen() {
return delegate.isOpen();
}
@Override
public ProviderConnection getProviderConnection() {
return delegate.getProviderConnection();
}
@Override
public ConnectionConfig getConnectionConfig() {
return delegate.getConnectionConfig();
}
@Override
public void close(RequestControl[] controls) {
try {
if(isDebugEnabled && delegate != null && delegate.isOpen()) {
log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet());
}
} catch (Throwable e) {
//ignore
}
try {
delegate.close(controls);
} finally {
restoreClassLoader();
}
}
@Override
public void close() {
try {
if(isDebugEnabled && delegate != null && delegate.isOpen()) {
log.debug("Closed a connection, total count is now {}", CONNECTION_COUNTER.decrementAndGet());
}
} catch (Throwable e) {
//ignore
}
try {
delegate.close();
} finally {
restoreClassLoader();
}
}
private void restoreClassLoader() {
if (needRestore) {
restoreClassLoader0(cl);
}
}
};
}