GUACAMOLE-243: Finish up changes to deal with LDAP referrals, both in UserServer and ConnectionServer classes, along with global changes in LDAPConnectionService class.

This commit is contained in:
Nick Couchman
2017-03-18 11:08:56 -04:00
committed by Nick Couchman
parent d98cdd2917
commit 242cfbaf85
3 changed files with 104 additions and 49 deletions

View File

@@ -118,13 +118,16 @@ public class LDAPConnectionService {
if (ldapConstraints == null) if (ldapConstraints == null)
ldapConstraints = new LDAPConstraints(); ldapConstraints = new LDAPConstraints();
// Set whether or not we follow referrals, and max hops // Set whether or not we follow referrals
ldapConstraints.setReferralFollowing(confService.getFollowReferrals()); ldapConstraints.setReferralFollowing(confService.getFollowReferrals());
String refAuthMethod = confService.getReferralAuthentication();
// If the referral auth method is set to bind, we set it using the existing
// username and password.
String refAuthMethod = confService.getReferralAuthentication();
if (refAuthMethod != null && refAuthMethod.equals("bind")) if (refAuthMethod != null && refAuthMethod.equals("bind"))
ldapConstraints.setReferralHandler(new ReferralAuthHandler(userDN, password)); ldapConstraints.setReferralHandler(new ReferralAuthHandler(userDN, password));
// Set the maximum number of referrals we follow
ldapConstraints.setHopLimit(confService.getMaxReferralHops()); ldapConstraints.setHopLimit(confService.getMaxReferralHops());
// Set timelimit to wait for LDAP operations, converting to ms // Set timelimit to wait for LDAP operations, converting to ms

View File

@@ -24,6 +24,7 @@ import com.novell.ldap.LDAPAttribute;
import com.novell.ldap.LDAPConnection; import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPEntry; import com.novell.ldap.LDAPEntry;
import com.novell.ldap.LDAPException; import com.novell.ldap.LDAPException;
import com.novell.ldap.LDAPReferralException;
import com.novell.ldap.LDAPSearchResults; import com.novell.ldap.LDAPSearchResults;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
@@ -129,62 +130,80 @@ public class ConnectionService {
Map<String, Connection> connections = new HashMap<String, Connection>(); Map<String, Connection> connections = new HashMap<String, Connection>();
while (results.hasMore()) { while (results.hasMore()) {
LDAPEntry entry = results.next(); try {
// Get common name (CN) LDAPEntry entry = results.next();
LDAPAttribute cn = entry.getAttribute("cn");
if (cn == null) {
logger.warn("guacConfigGroup is missing a cn.");
continue;
}
// Get associated protocol // Get common name (CN)
LDAPAttribute protocol = entry.getAttribute("guacConfigProtocol"); LDAPAttribute cn = entry.getAttribute("cn");
if (protocol == null) { if (cn == null) {
logger.warn("guacConfigGroup \"{}\" is missing the " logger.warn("guacConfigGroup is missing a cn.");
+ "required \"guacConfigProtocol\" attribute.", continue;
cn.getStringValue()); }
continue;
}
// Set protocol // Get associated protocol
GuacamoleConfiguration config = new GuacamoleConfiguration(); LDAPAttribute protocol = entry.getAttribute("guacConfigProtocol");
config.setProtocol(protocol.getStringValue()); if (protocol == null) {
logger.warn("guacConfigGroup \"{}\" is missing the "
+ "required \"guacConfigProtocol\" attribute.",
cn.getStringValue());
continue;
}
// Get parameters, if any // Set protocol
LDAPAttribute parameterAttribute = entry.getAttribute("guacConfigParameter"); GuacamoleConfiguration config = new GuacamoleConfiguration();
if (parameterAttribute != null) { config.setProtocol(protocol.getStringValue());
// For each parameter // Get parameters, if any
Enumeration<?> parameters = parameterAttribute.getStringValues(); LDAPAttribute parameterAttribute = entry.getAttribute("guacConfigParameter");
while (parameters.hasMoreElements()) { if (parameterAttribute != null) {
String parameter = (String) parameters.nextElement(); // For each parameter
Enumeration<?> parameters = parameterAttribute.getStringValues();
while (parameters.hasMoreElements()) {
// Parse parameter String parameter = (String) parameters.nextElement();
int equals = parameter.indexOf('=');
if (equals != -1) {
// Parse name // Parse parameter
String name = parameter.substring(0, equals); int equals = parameter.indexOf('=');
String value = parameter.substring(equals+1); if (equals != -1) {
config.setParameter(name, value); // Parse name
String name = parameter.substring(0, equals);
String value = parameter.substring(equals+1);
config.setParameter(name, value);
}
} }
} }
// Filter the configuration, substituting all defined tokens
tokenFilter.filterValues(config.getParameters());
// Store connection using cn for both identifier and name
String name = cn.getStringValue();
Connection connection = new SimpleConnection(name, name, config);
connection.setParentIdentifier(LDAPAuthenticationProvider.ROOT_CONNECTION_GROUP);
connections.put(name, connection);
} }
// Filter the configuration, substituting all defined tokens // Deal with issues following LDAP referrals
tokenFilter.filterValues(config.getParameters()); catch (LDAPReferralException e) {
if (confService.getFollowReferrals()) {
// Store connection using cn for both identifier and name logger.error("Could not follow referral.", e.getMessage());
String name = cn.getStringValue(); logger.debug("Error encountered trying to follow referral.", e);
Connection connection = new SimpleConnection(name, name, config); throw new GuacamoleServerException("Could not follow LDAP referral.", e);
connection.setParentIdentifier(LDAPAuthenticationProvider.ROOT_CONNECTION_GROUP); }
connections.put(name, connection); else {
logger.warn("Given a referral, but referrals are disabled.", e.getMessage());
logger.debug("Got a referral, but configured to not follow them.", e);
continue;
}
}
} }
@@ -251,8 +270,23 @@ public class ConnectionService {
// The guacConfig group uses the seeAlso attribute to refer // The guacConfig group uses the seeAlso attribute to refer
// to these other groups // to these other groups
while (userRoleGroupResults.hasMore()) { while (userRoleGroupResults.hasMore()) {
LDAPEntry entry = userRoleGroupResults.next(); try {
connectionSearchFilter.append("(seeAlso=").append(escapingService.escapeLDAPSearchFilter(entry.getDN())).append(")"); LDAPEntry entry = userRoleGroupResults.next();
connectionSearchFilter.append("(seeAlso=").append(escapingService.escapeLDAPSearchFilter(entry.getDN())).append(")");
}
catch (LDAPReferralException e) {
if (confService.getFollowReferrals()) {
logger.error("Could not follow referral.", e.getMessage());
logger.debug("Error encountered trying to follow referral.", e);
throw new GuacamoleServerException("Could not follow LDAP referral.", e);
}
else {
logger.warn("Given a referral, but referrals are disabled.", e.getMessage());
logger.debug("Got a referral, but configured to not follow them.", e);
continue;
}
}
} }
} }

View File

@@ -125,15 +125,17 @@ public class UserService {
logger.warn("Possibly ambiguous user account: \"{}\".", identifier); logger.warn("Possibly ambiguous user account: \"{}\".", identifier);
} }
// Deal with errors trying to follow referrals
catch (LDAPReferralException e) { catch (LDAPReferralException e) {
if (confService.getFollowReferrals()) { if (confService.getFollowReferrals()) {
logger.error("Could not follow referral.", e.getMessage()); logger.error("Could not follow referral.", e.getMessage());
logger.debug("Error encountered trying to follow referral.", e); logger.debug("Error encountered trying to follow referral.", e);
throw new GuacamoleException("Could not follow LDAP referral."); throw new GuacamoleServerException("Could not follow LDAP referral.", e);
} }
else { else {
logger.warn("Encountered a referral, but not following it.", e.getMessage()); logger.warn("Given a referral, but referrals are disabled.", e.getMessage());
logger.debug("Got a referral, but not configured to follow it.", e); logger.debug("Got a referral, but configured to not follow them.", e);
continue; continue;
} }
} }
@@ -284,8 +286,24 @@ public class UserService {
// Add all DNs for found users // Add all DNs for found users
while (results.hasMore()) { while (results.hasMore()) {
LDAPEntry entry = results.next(); try {
userDNs.add(entry.getDN()); LDAPEntry entry = results.next();
userDNs.add(entry.getDN());
}
// Deal with errors following referrals
catch (LDAPReferralException e) {
if (confService.getFollowReferrals()) {
logger.error("Error trying to follow a referral.", e.getMessage());
logger.debug("Encountered an error trying to follow a referral.", e);
throw new GuacamoleServerException("Failed while trying to follow referrals.", e);
}
else {
logger.warn("Given a referral, not following it.", e.getMessage());
logger.debug("Given a referral, but configured to not follow them.", e);
continue;
}
}
} }
// Return all discovered DNs (if any) // Return all discovered DNs (if any)