Commit 8a9b33c7 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Alternate DN and base DN are treated as one. JM-722

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@5715 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4fdfd5a6
...@@ -124,10 +124,8 @@ ...@@ -124,10 +124,8 @@
</li> </li>
<li>ldap.alternateBaseDN -- a second DN in the directory can optionally be set. If set, the <li>ldap.alternateBaseDN -- a second DN in the directory can optionally be set. If set, the
alternate base DN alternate base DN will be used for authentication, loading single users and displaying a
will be used for authentication and loading single users, but will not be used to display a list of users. Content in the base DN and the alternate DN will be treated as one.
list of users
(due to technical limitations).
<li>ldap.adminDN -- a directory administrator's DN. All directory operations will be <li>ldap.adminDN -- a directory administrator's DN. All directory operations will be
performed performed
with this account. The admin must be able to perform searches and load user records. The with this account. The admin must be able to perform searches and load user records. The
......
...@@ -318,15 +318,25 @@ public class LdapManager { ...@@ -318,15 +318,25 @@ public class LdapManager {
/** /**
* Returns a DirContext for the LDAP server that can be used to perform * Returns a DirContext for the LDAP server that can be used to perform
* lookups and searches using the default base DN. The context uses the * lookups and searches using the default base DN. The alternate DN will be used
* in case there is a {@link NamingException} using base DN. The context uses the
* admin login that is defined by <tt>adminDN</tt> and <tt>adminPassword</tt>. * admin login that is defined by <tt>adminDN</tt> and <tt>adminPassword</tt>.
* *
* @return a connection to the LDAP server. * @return a connection to the LDAP server.
* @throws NamingException if there is an error making the LDAP connection. * @throws NamingException if there is an error making the LDAP connection.
*/ */
public LdapContext getContext() throws NamingException { public LdapContext getContext() throws NamingException {
try {
return getContext(baseDN); return getContext(baseDN);
} }
catch (NamingException e) {
if (alternateBaseDN != null) {
return getContext(alternateBaseDN);
} else {
throw(e);
}
}
}
/** /**
* Returns a DirContext for the LDAP server that can be used to perform * Returns a DirContext for the LDAP server that can be used to perform
...@@ -624,6 +634,7 @@ public class LdapManager { ...@@ -624,6 +634,7 @@ public class LdapManager {
if (userDN.startsWith("ldap://")) { if (userDN.startsWith("ldap://")) {
userDN = userDN.replace("," + baseDN, ""); userDN = userDN.replace("," + baseDN, "");
userDN = userDN.substring(userDN.lastIndexOf("/") + 1); userDN = userDN.substring(userDN.lastIndexOf("/") + 1);
userDN = java.net.URLDecoder.decode(userDN, "UTF-8");
} }
if (encloseUserDN) { if (encloseUserDN) {
// Enclose userDN values between " // Enclose userDN values between "
...@@ -908,6 +919,32 @@ public class LdapManager { ...@@ -908,6 +919,32 @@ public class LdapManager {
} }
} }
/**
* Returns the BaseDN for the given username.
*
* @param username username to return its base DN.
* @return the BaseDN for the given username. If no baseDN is found,
* this method will return <tt>null</tt>.
*/
public String getUsersBaseDN(String username) {
try {
findUserDN(username, baseDN);
return baseDN;
}
catch (Exception e) {
try {
if (alternateBaseDN != null) {
findUserDN(username, alternateBaseDN);
return alternateBaseDN;
}
}
catch (Exception ex) {
Log.debug(ex);
}
}
return null;
}
/** /**
* Returns the starting admin DN that searches for admins will performed with. * Returns the starting admin DN that searches for admins will performed with.
* Searches will performed on the entire sub-tree under the admin DN. * Searches will performed on the entire sub-tree under the admin DN.
......
...@@ -38,12 +38,16 @@ public class LdapUserProvider implements UserProvider { ...@@ -38,12 +38,16 @@ public class LdapUserProvider implements UserProvider {
private static SimpleDateFormat ldapDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); private static SimpleDateFormat ldapDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
private LdapManager manager; private LdapManager manager;
private String baseDN;
private String alternateBaseDN;
private Map<String, String> searchFields; private Map<String, String> searchFields;
private int userCount = -1; private int userCount = -1;
private long expiresStamp = System.currentTimeMillis(); private long expiresStamp = System.currentTimeMillis();
public LdapUserProvider() { public LdapUserProvider() {
manager = LdapManager.getInstance(); manager = LdapManager.getInstance();
baseDN = manager.getBaseDN();
alternateBaseDN = manager.getAlternateBaseDN();
searchFields = new LinkedHashMap<String,String>(); searchFields = new LinkedHashMap<String,String>();
String fieldList = JiveGlobals.getXMLProperty("ldap.searchFields"); String fieldList = JiveGlobals.getXMLProperty("ldap.searchFields");
// If the value isn't present, default to to username, name, and email. // If the value isn't present, default to to username, name, and email.
...@@ -76,7 +80,7 @@ public class LdapUserProvider implements UserProvider { ...@@ -76,7 +80,7 @@ public class LdapUserProvider implements UserProvider {
manager.getUsernameField(), manager.getNameField(), manager.getUsernameField(), manager.getNameField(),
manager.getEmailField(), "createTimestamp", "modifyTimestamp" manager.getEmailField(), "createTimestamp", "modifyTimestamp"
}; };
ctx = manager.getContext(); ctx = manager.getContext(manager.getUsersBaseDN(username));
Attributes attrs = ctx.getAttributes(userDN, attributes); Attributes attrs = ctx.getAttributes(userDN, attributes);
String name = null; String name = null;
Attribute nameField = attrs.get(manager.getNameField()); Attribute nameField = attrs.get(manager.getNameField());
...@@ -134,8 +138,9 @@ public class LdapUserProvider implements UserProvider { ...@@ -134,8 +138,9 @@ public class LdapUserProvider implements UserProvider {
} }
int count = 0; int count = 0;
DirContext ctx = null; DirContext ctx = null;
DirContext ctx2 = null;
try { try {
ctx = manager.getContext(); ctx = manager.getContext(baseDN);
// Search for the dn based on the username. // Search for the dn based on the username.
SearchControls searchControls = new SearchControls(); SearchControls searchControls = new SearchControls();
// See if recursive searching is enabled. Otherwise, only search one level. // See if recursive searching is enabled. Otherwise, only search one level.
...@@ -152,6 +157,15 @@ public class LdapUserProvider implements UserProvider { ...@@ -152,6 +157,15 @@ public class LdapUserProvider implements UserProvider {
count++; count++;
answer.nextElement(); answer.nextElement();
} }
// Add count of users found in alternate DN
if (alternateBaseDN != null) {
ctx2 = manager.getContext(alternateBaseDN);
answer = ctx2.search("", filter, searchControls);
while (answer.hasMoreElements()) {
count++;
answer.nextElement();
}
}
// Close the enumeration. // Close the enumeration.
answer.close(); answer.close();
} }
...@@ -167,6 +181,14 @@ public class LdapUserProvider implements UserProvider { ...@@ -167,6 +181,14 @@ public class LdapUserProvider implements UserProvider {
catch (Exception ignored) { catch (Exception ignored) {
// Ignore. // Ignore.
} }
try {
if (ctx2 != null) {
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
} }
this.userCount = count; this.userCount = count;
this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5; this.expiresStamp = System.currentTimeMillis() + JiveConstants.MINUTE *5;
...@@ -179,10 +201,12 @@ public class LdapUserProvider implements UserProvider { ...@@ -179,10 +201,12 @@ public class LdapUserProvider implements UserProvider {
} }
public Collection<String> getUsernames() { public Collection<String> getUsernames() {
List<String> usernames = new ArrayList<String>(); Set<String> usernames = new HashSet<String>();
LdapContext ctx = null; LdapContext ctx = null;
LdapContext ctx2 = null;
try { try {
ctx = manager.getContext(); ctx = manager.getContext(baseDN);
// Sort on username field. // Sort on username field.
Control[] searchControl = new Control[]{ Control[] searchControl = new Control[]{
new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL) new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL)
...@@ -208,6 +232,20 @@ public class LdapUserProvider implements UserProvider { ...@@ -208,6 +232,20 @@ public class LdapUserProvider implements UserProvider {
// Escape username and add to results. // Escape username and add to results.
usernames.add(JID.escapeNode(username)); usernames.add(JID.escapeNode(username));
} }
// Add usernames found in alternate DN
if (alternateBaseDN != null) {
ctx2 = manager.getContext(alternateBaseDN);
ctx2.setRequestControls(searchControl);
answer = ctx2.search("", filter, searchControls);
while (answer.hasMoreElements()) {
// Get the next userID.
String username = (String) ((SearchResult) answer.next()).getAttributes().get(
manager.getUsernameField()).get();
// Escape username and add to results.
usernames.add(JID.escapeNode(username));
}
}
// Close the enumeration. // Close the enumeration.
answer.close(); answer.close();
} }
...@@ -224,10 +262,19 @@ public class LdapUserProvider implements UserProvider { ...@@ -224,10 +262,19 @@ public class LdapUserProvider implements UserProvider {
catch (Exception ignored) { catch (Exception ignored) {
// Ignore. // Ignore.
} }
try {
if (ctx2 != null) {
ctx2.setRequestControls(null);
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
} }
// If client-side sorting is enabled, do it. // If client-side sorting is enabled, do it.
if (Boolean.valueOf(JiveGlobals.getXMLProperty("ldap.clientSideSorting"))) { if (Boolean.valueOf(JiveGlobals.getXMLProperty("ldap.clientSideSorting"))) {
Collections.sort(usernames); Collections.sort(new ArrayList<String>(usernames));
} }
return usernames; return usernames;
} }
...@@ -235,8 +282,10 @@ public class LdapUserProvider implements UserProvider { ...@@ -235,8 +282,10 @@ public class LdapUserProvider implements UserProvider {
public Collection<User> getUsers(int startIndex, int numResults) { public Collection<User> getUsers(int startIndex, int numResults) {
List<String> usernames = new ArrayList<String>(); List<String> usernames = new ArrayList<String>();
LdapContext ctx = null; LdapContext ctx = null;
LdapContext ctx2 = null;
try { try {
ctx = manager.getContext(); ctx = manager.getContext(baseDN);
// Sort on username field. // Sort on username field.
Control[] searchControl = new Control[]{ Control[] searchControl = new Control[]{
new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL) new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL)
...@@ -261,6 +310,12 @@ public class LdapUserProvider implements UserProvider { ...@@ -261,6 +310,12 @@ public class LdapUserProvider implements UserProvider {
String filter = MessageFormat.format(manager.getSearchFilter(), "*"); String filter = MessageFormat.format(manager.getSearchFilter(), "*");
NamingEnumeration answer = ctx.search("", filter, searchControls); NamingEnumeration answer = ctx.search("", filter, searchControls);
// If client-side sorting is enabled, read in all results, sort, then get a sublist. // If client-side sorting is enabled, read in all results, sort, then get a sublist.
NamingEnumeration answer2 = null;
if (alternateBaseDN != null) {
ctx2 = manager.getContext(alternateBaseDN);
ctx2.setRequestControls(searchControl);
answer2 = ctx2.search("", filter, searchControls);
}
if (Boolean.valueOf(JiveGlobals.getXMLProperty("ldap.clientSideSorting"))) { if (Boolean.valueOf(JiveGlobals.getXMLProperty("ldap.clientSideSorting"))) {
while (answer.hasMoreElements()) { while (answer.hasMoreElements()) {
// Get the next userID. // Get the next userID.
...@@ -269,7 +324,16 @@ public class LdapUserProvider implements UserProvider { ...@@ -269,7 +324,16 @@ public class LdapUserProvider implements UserProvider {
// Escape username and add to results. // Escape username and add to results.
usernames.add(JID.escapeNode(username)); usernames.add(JID.escapeNode(username));
} }
Collections.sort(usernames); if (alternateBaseDN != null) {
while (answer2.hasMoreElements()) {
// Get the next userID.
String username = (String) ((SearchResult) answer2.next()).getAttributes().get(
manager.getUsernameField()).get();
// Escape username and add to results.
usernames.add(JID.escapeNode(username));
}
}
Collections.sort(new ArrayList<String>(usernames));
int endIndex = Math.min(startIndex + numResults, usernames.size()-1); int endIndex = Math.min(startIndex + numResults, usernames.size()-1);
usernames = usernames.subList(startIndex, endIndex); usernames = usernames.subList(startIndex, endIndex);
} }
...@@ -278,8 +342,9 @@ public class LdapUserProvider implements UserProvider { ...@@ -278,8 +342,9 @@ public class LdapUserProvider implements UserProvider {
for (int i=0; i < startIndex; i++) { for (int i=0; i < startIndex; i++) {
if (answer.hasMoreElements()) { if (answer.hasMoreElements()) {
answer.next(); answer.next();
} } else if (alternateBaseDN != null && answer2.hasMoreElements()) {
else { answer2.next();
} else {
return Collections.emptyList(); return Collections.emptyList();
} }
} }
...@@ -291,8 +356,13 @@ public class LdapUserProvider implements UserProvider { ...@@ -291,8 +356,13 @@ public class LdapUserProvider implements UserProvider {
manager.getUsernameField()).get(); manager.getUsernameField()).get();
// Escape username and add to results. // Escape username and add to results.
usernames.add(JID.escapeNode(username)); usernames.add(JID.escapeNode(username));
} } else if (alternateBaseDN != null && answer2.hasMoreElements()) {
else { // Get the next userID.
String username = (String) ((SearchResult) answer2.next()).getAttributes().get(
manager.getUsernameField()).get();
// Escape username and add to results.
usernames.add(JID.escapeNode(username));
} else {
break; break;
} }
} }
...@@ -313,6 +383,15 @@ public class LdapUserProvider implements UserProvider { ...@@ -313,6 +383,15 @@ public class LdapUserProvider implements UserProvider {
catch (Exception ignored) { catch (Exception ignored) {
// Ignore. // Ignore.
} }
try {
if (ctx2 != null) {
ctx2.setRequestControls(null);
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
} }
return new UserCollection(usernames.toArray(new String[usernames.size()])); return new UserCollection(usernames.toArray(new String[usernames.size()]));
} }
...@@ -353,8 +432,9 @@ public class LdapUserProvider implements UserProvider { ...@@ -353,8 +432,9 @@ public class LdapUserProvider implements UserProvider {
} }
List<String> usernames = new ArrayList<String>(); List<String> usernames = new ArrayList<String>();
LdapContext ctx = null; LdapContext ctx = null;
LdapContext ctx2 = null;
try { try {
ctx = manager.getContext(); ctx = manager.getContext(baseDN);
// Sort on username field. // Sort on username field.
Control[] searchControl = new Control[]{ Control[] searchControl = new Control[]{
new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL) new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL)
...@@ -390,6 +470,18 @@ public class LdapUserProvider implements UserProvider { ...@@ -390,6 +470,18 @@ public class LdapUserProvider implements UserProvider {
// Escape username and add to results. // Escape username and add to results.
usernames.add(JID.escapeNode(username)); usernames.add(JID.escapeNode(username));
} }
if (alternateBaseDN != null) {
ctx2 = manager.getContext(alternateBaseDN);
ctx2.setRequestControls(searchControl);
answer = ctx2.search("", filter.toString(), searchControls);
while (answer.hasMoreElements()) {
// Get the next userID.
String username = (String)((SearchResult)answer.next()).getAttributes().get(
manager.getUsernameField()).get();
// Escape username and add to results.
usernames.add(JID.escapeNode(username));
}
}
// Close the enumeration. // Close the enumeration.
answer.close(); answer.close();
// If client-side sorting is enabled, sort. // If client-side sorting is enabled, sort.
...@@ -410,6 +502,15 @@ public class LdapUserProvider implements UserProvider { ...@@ -410,6 +502,15 @@ public class LdapUserProvider implements UserProvider {
catch (Exception ignored) { catch (Exception ignored) {
// Ignore. // Ignore.
} }
try {
if (ctx2 != null) {
ctx2.setRequestControls(null);
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
} }
return new UserCollection(usernames.toArray(new String[usernames.size()])); return new UserCollection(usernames.toArray(new String[usernames.size()]));
} }
...@@ -425,8 +526,9 @@ public class LdapUserProvider implements UserProvider { ...@@ -425,8 +526,9 @@ public class LdapUserProvider implements UserProvider {
} }
List<String> usernames = new ArrayList<String>(); List<String> usernames = new ArrayList<String>();
LdapContext ctx = null; LdapContext ctx = null;
LdapContext ctx2 = null;
try { try {
ctx = manager.getContext(); ctx = manager.getContext(baseDN);
// Sort on username field. // Sort on username field.
Control[] searchControl = new Control[]{ Control[] searchControl = new Control[]{
new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL) new SortControl(new String[]{manager.getUsernameField()}, Control.NONCRITICAL)
...@@ -456,10 +558,20 @@ public class LdapUserProvider implements UserProvider { ...@@ -456,10 +558,20 @@ public class LdapUserProvider implements UserProvider {
} }
// TODO: used paged results if supported by LDAP server. // TODO: used paged results if supported by LDAP server.
NamingEnumeration answer = ctx.search("", filter.toString(), searchControls); NamingEnumeration answer = ctx.search("", filter.toString(), searchControls);
NamingEnumeration answer2 = null;
if(alternateBaseDN != null) {
ctx2 = manager.getContext(alternateBaseDN);
ctx2.setRequestControls(searchControl);
answer2 = ctx2.search("", filter.toString(), searchControls);
}
for (int i=0; i < startIndex; i++) { for (int i=0; i < startIndex; i++) {
if (answer.hasMoreElements()) { if (answer.hasMoreElements()) {
answer.next(); answer.next();
} }
else if (alternateBaseDN != null && answer2.hasMoreElements())
{
answer2.next();
}
else { else {
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -473,6 +585,14 @@ public class LdapUserProvider implements UserProvider { ...@@ -473,6 +585,14 @@ public class LdapUserProvider implements UserProvider {
// Escape username and add to results. // Escape username and add to results.
usernames.add(JID.escapeNode(username)); usernames.add(JID.escapeNode(username));
} }
else if (alternateBaseDN != null && answer2.hasMoreElements())
{
// Get the next userID.
String username = (String)((SearchResult)answer2.next()).getAttributes().get(
manager.getUsernameField()).get();
// Escape username and add to results.
usernames.add(JID.escapeNode(username));
}
else { else {
break; break;
} }
...@@ -498,6 +618,15 @@ public class LdapUserProvider implements UserProvider { ...@@ -498,6 +618,15 @@ public class LdapUserProvider implements UserProvider {
catch (Exception ignored) { catch (Exception ignored) {
// Ignore. // Ignore.
} }
try {
if (ctx2 != null) {
ctx2.setRequestControls(null);
ctx2.close();
}
}
catch (Exception ignored) {
// Ignore.
}
} }
return new UserCollection(usernames.toArray(new String[usernames.size()])); return new UserCollection(usernames.toArray(new String[usernames.size()]));
} }
......
...@@ -136,7 +136,7 @@ public class LdapVCardProvider implements VCardProvider { ...@@ -136,7 +136,7 @@ public class LdapVCardProvider implements VCardProvider {
try { try {
String userDN = manager.findUserDN(username); String userDN = manager.findUserDN(username);
ctx = manager.getContext(); ctx = manager.getContext(manager.getUsersBaseDN(username));
Attributes attrs = ctx.getAttributes(userDN, template.getAttributes()); Attributes attrs = ctx.getAttributes(userDN, template.getAttributes());
for (String attribute : template.getAttributes()) { for (String attribute : template.getAttributes()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment