From 7399fdb018d2248ec36edb30f5339cdcafbe2e98 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 13 Jan 2010 17:19:12 +0000
Subject: [PATCH] Fix for issues https://opends.dev.java.net/issues/show_bug.cgi?id=4484 and https://opends.dev.java.net/issues/show_bug.cgi?id=4485.
---
opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 157 insertions(+), 10 deletions(-)
diff --git a/opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java b/opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java
index 1dbbb2c..87c9783 100644
--- a/opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java
+++ b/opends/src/guitools/org/opends/guitools/controlpanel/browser/NodeRefresher.java
@@ -22,11 +22,13 @@
* CDDL HEADER END
*
*
- * Copyright 2008-2009 Sun Microsystems, Inc.
+ * Copyright 2008-2010 Sun Microsystems, Inc.
*/
package org.opends.guitools.controlpanel.browser;
+import static org.opends.messages.AdminToolMessages.*;
+
import java.util.ArrayList;
import java.util.Set;
@@ -42,26 +44,29 @@
import javax.swing.SwingUtilities;
import javax.swing.tree.TreeNode;
+import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.guitools.controlpanel.ui.nodes.BasicNode;
import org.opends.messages.AdminToolMessages;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.LDAPURL;
+import org.opends.server.types.OpenDsException;
import org.opends.server.types.RDN;
+import org.opends.server.types.SearchScope;
/**
* The class that is in charge of doing the LDAP searches required to update a
* node: search the local entry, detect if it has children, retrieve the
* attributes required to render the node, etc.
*/
-class NodeRefresher extends AbstractNodeTask {
+public class NodeRefresher extends AbstractNodeTask {
/**
* The enumeration containing all the states the refresher can have.
*
*/
- enum State
+ public enum State
{
/**
* The refresher is queued, but not started.
@@ -464,6 +469,14 @@
InitialLdapContext ctx = null;
try {
url = LDAPURL.decode(referral[i], false);
+ if (url.getHost() == null)
+ {
+ // Use the local server connection.
+ ctx = controller.getUserDataConnection();
+ url.setHost(ConnectionUtils.getHostName(ctx));
+ url.setPort(ConnectionUtils.getPort(ctx));
+ url.setScheme(ConnectionUtils.isSSL(ctx)?"ldaps":"ldap");
+ }
ctx = connectionPool.getConnection(url);
remoteDn = url.getRawBaseDN();
if ((remoteDn == null) ||
@@ -482,21 +495,39 @@
remoteDn, url.getAttributes(), url.getScope(), url.getRawFilter(),
url.getExtensions());
}
- if (useCustomFilter())
+ if (useCustomFilter() && url.getScope() == SearchScope.BASE_OBJECT)
{
// Check that the entry verifies the filter
searchForCustomFilter(remoteDn, ctx);
}
+
+ int scope = getJNDIScope(url);
+ String filter = getJNDIFilter(url);
+
SearchControls ctls = controller.getBasicSearchControls();
ctls.setReturningAttributes(controller.getAttrsForBlackSearch());
- ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
+ ctls.setSearchScope(scope);
+ ctls.setCountLimit(1);
NamingEnumeration<SearchResult> sr = ctx.search(remoteDn,
- controller.getObjectSearchFilter(),
- ctls);
+ filter,
+ ctls);
if (sr.hasMore())
{
entry = sr.next();
- entry.setName(remoteDn);
+ String name;
+ if (entry.getName().length() == 0)
+ {
+ name = remoteDn;
+ }
+ else
+ {
+ name = unquoteRelativeName(entry.getName())+","+remoteDn;
+ }
+ entry.setName(name);
+ }
+ else
+ {
+ throw new NameNotFoundException();
}
throwAbandonIfNeeded(null);
}
@@ -522,7 +553,17 @@
throw new SearchAbandonException(
State.FAILED, lastException, lastExceptionArg);
}
- else {
+ else
+ {
+ if (url.getScope() != SearchScope.BASE_OBJECT)
+ {
+ // The URL is to be transformed: the code assumes that the URL points
+ // to the remote entry.
+ url = new LDAPURL(url.getScheme(), url.getHost(),
+ url.getPort(), entry.getName(), url.getAttributes(),
+ SearchScope.BASE_OBJECT, null, url.getExtensions());
+ }
+ checkLoopInReferral(url, referral[i-1]);
remoteUrl = url;
remoteEntry = entry;
}
@@ -877,7 +918,7 @@
/**
* Transform an exception into a TaskAbandonException.
* If no exception is passed, the routine checks if the task has
- * been cancelled and throws an TaskAbandonException accordingly.
+ * been canceled and throws an TaskAbandonException accordingly.
* @param x the exception.
* @throws SearchAbandonException if the task/refresher must be abandoned.
*/
@@ -970,4 +1011,110 @@
}
return result;
}
+
+ /**
+ * Returns the scope to be used in a JNDI request based on the information
+ * of an LDAP URL.
+ * @param url the LDAP URL.
+ * @return the scope to be used in a JNDI request.
+ */
+ private int getJNDIScope(LDAPURL url)
+ {
+ int scope;
+ if (url.getScope() != null)
+ {
+ switch (url.getScope())
+ {
+ case BASE_OBJECT:
+ scope = SearchControls.OBJECT_SCOPE;
+ break;
+ case WHOLE_SUBTREE:
+ scope = SearchControls.SUBTREE_SCOPE;
+ break;
+ case SUBORDINATE_SUBTREE:
+ scope = SearchControls.ONELEVEL_SCOPE;
+ break;
+ case SINGLE_LEVEL:
+ scope = SearchControls.ONELEVEL_SCOPE;
+ break;
+ default:
+ scope = SearchControls.OBJECT_SCOPE;
+ }
+ }
+ else
+ {
+ scope = SearchControls.OBJECT_SCOPE;
+ }
+ return scope;
+ }
+
+ /**
+ * Returns the filter to be used in a JNDI request based on the information
+ * of an LDAP URL.
+ * @param url the LDAP URL.
+ * @return the filter.
+ */
+ private String getJNDIFilter(LDAPURL url)
+ {
+ String filter = url.getRawFilter();
+ if (filter == null)
+ {
+ filter = controller.getObjectSearchFilter();
+ }
+ return filter;
+ }
+
+ /**
+ * Check that there is no loop in terms of DIT (the check basically identifies
+ * whether we are pointing to an entry above in the same server).
+ * @param url the URL to the remote entry. It is assumed that the base DN
+ * of the URL points to the remote entry.
+ * @param referral the referral used to retrieve the remote entry.
+ * @throws SearchAbandonException if there is a loop issue (the remoteEntry
+ * is actually an entry in the same server as the local entry but above in the
+ * DIT).
+ */
+ private void checkLoopInReferral(LDAPURL url,
+ String referral) throws SearchAbandonException
+ {
+ boolean checkSucceeded = true;
+ try
+ {
+ DN dn1 = DN.decode(getNode().getDN());
+ DN dn2 = url.getBaseDN();
+ if (dn2.isAncestorOf(dn1))
+ {
+ String host = url.getHost();
+ int port = url.getPort();
+ String adminHost = ConnectionUtils.getHostName(
+ controller.getConfigurationConnection());
+ int adminPort =
+ ConnectionUtils.getPort(controller.getConfigurationConnection());
+ checkSucceeded = (port != adminPort) ||
+ !adminHost.equalsIgnoreCase(host);
+
+ if (checkSucceeded)
+ {
+ String hostUserData = ConnectionUtils.getHostName(
+ controller.getUserDataConnection());
+ int portUserData =
+ ConnectionUtils.getPort(controller.getUserDataConnection());
+ checkSucceeded = (port != portUserData) ||
+ !hostUserData.equalsIgnoreCase(host);
+ }
+ }
+ }
+ catch (OpenDsException odse)
+ {
+ // Ignore
+ }
+ if (!checkSucceeded)
+ {
+ String hostPort = ServerDescriptor.getServerRepresentation(url.getHost(),
+ url.getPort());
+ throw new SearchAbandonException(
+ State.FAILED, new ReferralLimitExceededException(
+ ERR_CTRL_PANEL_REFERRAL_LOOP.get(url.getRawBaseDN())), referral);
+ }
+ }
}
--
Gitblit v1.10.0