in artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/jaas/LDAPLoginModule.java [341:481]
private String resolveDN(String username, List<String> roles) throws FailedLoginException {
String dn = null;
logger.debug("Create the LDAP initial context.");
try {
openContext();
} catch (Exception ne) {
FailedLoginException ex = new FailedLoginException("Error opening LDAP connection");
ex.initCause(ne);
throw ex;
}
if (!isLoginPropertySet(ConfigKey.USER_SEARCH_MATCHING)) {
return username;
}
MessageFormat userSearchMatchingFormat = new MessageFormat(getLDAPPropertyValue(ConfigKey.USER_SEARCH_MATCHING));
boolean userSearchSubtreeBool = Boolean.parseBoolean(getLDAPPropertyValue(ConfigKey.USER_SEARCH_SUBTREE));
boolean ignorePartialResultExceptionBool = Boolean.parseBoolean(getLDAPPropertyValue(ConfigKey.IGNORE_PARTIAL_RESULT_EXCEPTION));
try {
String filter = userSearchMatchingFormat.format(new String[]{doRFC2254Encoding(username)});
SearchControls constraints = new SearchControls();
if (userSearchSubtreeBool) {
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
} else {
constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
}
// setup attributes
List<String> list = new ArrayList<>();
if (isLoginPropertySet(ConfigKey.USER_ROLE_NAME)) {
list.add(getLDAPPropertyValue(ConfigKey.USER_ROLE_NAME));
}
String[] attribs = new String[list.size()];
list.toArray(attribs);
constraints.setReturningAttributes(attribs);
if (logger.isDebugEnabled()) {
logger.debug("Get the user DN.");
logger.debug("Looking for the user in LDAP with ");
logger.debug(" base DN: {}", getLDAPPropertyValue(ConfigKey.USER_BASE));
logger.debug(" filter: {}", filter);
}
NamingEnumeration<SearchResult> results = null;
try {
results = Subject.doAs(brokerGssapiIdentity, (PrivilegedExceptionAction< NamingEnumeration<SearchResult>>) () -> context.search(getLDAPPropertyValue(ConfigKey.USER_BASE), filter, constraints));
} catch (PrivilegedActionException e) {
Exception cause = e.getException();
FailedLoginException ex = new FailedLoginException("Error executing search query to resolve DN");
ex.initCause(cause);
throw ex;
}
if (results == null || !results.hasMore()) {
throw new FailedLoginException("User " + username + " not found in LDAP.");
}
SearchResult result = results.next();
try {
if (results.hasMore()) {
// ignore for now
}
} catch (PartialResultException e) {
// Workaround for AD servers not handling referrals correctly.
if (ignorePartialResultExceptionBool) {
logger.debug("PartialResultException encountered and ignored", e);
} else {
throw e;
}
}
if (result.isRelative()) {
logger.debug("LDAP returned a relative name: {}", result.getName());
NameParser parser = context.getNameParser("");
Name contextName = parser.parse(context.getNameInNamespace());
Name baseName = parser.parse(getLDAPPropertyValue(ConfigKey.USER_BASE));
Name entryName = parser.parse(result.getName());
Name name = contextName.addAll(baseName);
name = name.addAll(entryName);
dn = name.toString();
} else {
logger.debug("LDAP returned an absolute name: {}", result.getName());
try {
URI uri = new URI(result.getName());
String path = uri.getPath();
if (path.startsWith("/")) {
dn = path.substring(1);
} else {
dn = path;
}
} catch (URISyntaxException e) {
closeContext();
FailedLoginException ex = new FailedLoginException("Error parsing absolute name as URI.");
ex.initCause(e);
throw ex;
}
}
logger.debug("Using DN [{}] for binding.", dn);
Attributes attrs = result.getAttributes();
if (attrs == null) {
throw new FailedLoginException("User found, but LDAP entry malformed: " + username);
}
if (isLoginPropertySet(ConfigKey.USER_ROLE_NAME)) {
Attribute roleNames = attrs.get(getLDAPPropertyValue(ConfigKey.USER_ROLE_NAME));
if (roleNames != null) {
NamingEnumeration<?> e = roleNames.getAll();
while (e.hasMore()) {
String roleDnString = (String) e.next();
if (isRoleAttributeSet) {
// parse out the attribute from the group Dn
LdapName ldapRoleName = new LdapName(roleDnString);
for (int i = 0; i < ldapRoleName.size(); i++) {
Rdn candidate = ldapRoleName.getRdn(i);
if (roleAttributeName.equals(candidate.getType())) {
roles.add((String) candidate.getValue());
}
}
} else {
roles.add(roleDnString);
}
}
}
}
} catch (NamingException e) {
closeContext();
FailedLoginException ex = new FailedLoginException("Error contacting LDAP");
ex.initCause(e);
throw ex;
}
return dn;
}