mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

jvergara
08.00.2007 7886f35b46cac515f73de8c6af33b8d8df3e2a3b
Commit quite a lot of bug fixes to the ADS.

The fixes included the handling of quite a lot of errors that might be generated by the Administration Framework.

The creation of the Administrators has been revisited and now they use the privilege system and no acis are defined (which implies that no modification to the configuration is required in order the administrators to work).
9 files modified
595 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/ADSContext.java 422 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContextException.java 7 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContextHelper.java 29 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java 8 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java 91 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/TopologyCache.java 3 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/TopologyCacheException.java 4 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java 2 ●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/util/ServerLoader.java 29 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -27,13 +27,15 @@
package org.opends.admin.ads;
import java.util.LinkedList;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.CompositeName;
import javax.naming.InvalidNameException;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
@@ -59,6 +61,8 @@
 */
public class ADSContext
{
  private static final Logger LOG =
    Logger.getLogger(ADSContext.class.getName());
  /**
   * Enumeration containing the different server properties that are stored in
   * the ADS.
@@ -68,7 +72,7 @@
    /**
     * The ID used to identify the server.
     */
    ID("cn"),
    ID("id"),
    /**
     * The host name of the server.
     */
@@ -238,11 +242,6 @@
    ADMINISTRATOR_DN
  };
  /**
   * Character used to separate hostname from ipath in RDN.
   */
  public final static String HNP_SEPARATOR = "@";
  // The context used to retrieve information
  InitialLdapContext dirContext;
@@ -404,43 +403,6 @@
  }
  /**
   * Returns the properties of a server for a given host name and installation
   * path.
   * @param hostname the host Name.
   * @param ipath the installation path.
   * @return the properties of a server for a given host name and installation
   * path.
   * @throws ADSContextException if something goes wrong.
   */
  public Map<ServerProperty, Object> lookupServerRegistry(String hostname,
      String ipath) throws ADSContextException
  {
    LdapName dn = makeDNFromHostnameAndPath(hostname, ipath);
    Map<ServerProperty, Object> result;
    try
    {
      result = makePropertiesFromServerAttrs(hostname, ipath,
          dirContext.getAttributes(dn));
    }
    catch (NameNotFoundException x)
    {
      result = null;
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns the member list of a group of server.
   *
   * @param serverGroupId
@@ -531,7 +493,7 @@
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<ServerProperty,Object> properties =
          makePropertiesFromServerAttrs(sr.getName(), sr.getAttributes());
          makePropertiesFromServerAttrs(sr.getAttributes());
        result.add(properties);
      }
    }
@@ -554,85 +516,6 @@
    return result;
  }
  /**
   * Returns a set of the server properties that are registered in the ADS and
   * that contain the properties specified in serverProperties.
   * @param serverProperties the properties that are used as search criteria.
   * @return a set of the server properties that are registered in the ADS and
   * that contain the properties specified in serverProperties.
   * @throws ADSContextException if something goes wrong.
   */
  public Set<Map<ServerProperty, Object>> searchServerRegistry(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    Set<Map<ServerProperty, Object>> result =
      new HashSet<Map<ServerProperty, Object>>();
    StringBuffer filter = new StringBuffer();
    // Build the filter according the properties passed in serverProperties
    int operandCount = 0;
    if (serverProperties.containsKey(ServerProperty.HOST_NAME))
    {
      filter.append("(cn=");
      filter.append(serverProperties.get(ServerProperty.HOST_NAME));
      filter.append("*");
      if (serverProperties.containsKey(ServerProperty.INSTANCE_PATH))
      {
        filter.append(HNP_SEPARATOR);
        filter.append(serverProperties.get(ServerProperty.INSTANCE_PATH));
      }
      filter.append(")");
      operandCount++;
    }
    if (serverProperties.containsKey(ServerProperty.LDAP_PORT))
    {
      filter.append("(");
      filter.append(ServerProperty.LDAP_PORT);
      filter.append("=");
      filter.append(serverProperties.get(ServerProperty.LDAP_PORT));
      filter.append(")");
      operandCount++;
    }
    if (operandCount >= 2)
    {
      filter.insert(0, '(');
      filter.append("&)");
    }
    // Search the ADS
    try
    {
      NamingEnumeration ne;
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      ne = dirContext.search(getServerContainerDN(), filter.toString(), sc);
      while (ne.hasMore())
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<ServerProperty, Object> properties = makePropertiesFromServerAttrs(
            sr.getName(), sr.getAttributes());
        result.add(properties);
      }
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.BROKEN_INSTALL);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Creates a Server Group in the ADS.
@@ -648,8 +531,10 @@
    BasicAttributes attrs = makeAttrsFromServerGroupProperties(
        serverGroupProperties);
    // Add the objectclass attribute value
    attrs.put("objectclass", "top");
    attrs.put("objectclass", "groupOfUniqueNames");
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("groupOfUniqueNames");
    attrs.put(oc);
    try
    {
      DirContext ctx = dirContext.createSubcontext(dn, attrs);
@@ -678,7 +563,6 @@
      Map<ServerGroupProperty, Object> serverGroupProperties)
  throws ADSContextException
  {
    LdapName dn = nameFromDN("cn=" + Rdn.escapeValue(groupID) + "," +
        getServerGroupContainerDN());
    try
@@ -849,7 +733,7 @@
        Map<AdministratorProperty, Object> properties =
          makePropertiesFromAdministratorAttrs(
              sr.getName(), sr.getAttributes());
              getRdn(sr.getName()), sr.getAttributes());
        result.add(properties);
      }
@@ -890,9 +774,9 @@
    createAdministratorContainerEntry();
    createContainerEntry(getServerContainerDN());
    createContainerEntry(getServerGroupContainerDN());
    //setupACIOnServer(getDirContext(), true);
  }
  /**
   * Removes the administration data.
   * @throws ADSContextException if something goes wrong.
@@ -900,6 +784,7 @@
  public void removeAdminData() throws ADSContextException
  {
    removeAdministrationSuffix();
    //setupACIOnServer(getDirContext(), false);
  }
@@ -1055,8 +940,8 @@
   * otherwise.
   * @throws ADSContextException if the ACIs could not be set up.
   */
  public static boolean setupACIOnServer(LdapContext dirCtx,
      boolean enable) throws ADSContextException
  private boolean setupACIOnServer(LdapContext dirCtx, boolean enable)
  throws ADSContextException
  {
    boolean result;
    Attributes currentAttrs;
@@ -1065,12 +950,14 @@
    try
    {
      // Get the ACI value on the root entry
      currentAttrs = dirCtx.getAttributes("", new String[] { "aci" });
      currentAttr = currentAttrs.get("aci");
      // Get the ACI value on the global ACI
      String accessControlDn = "cn=Access Control Handler,cn=config";
      currentAttrs = dirCtx.getAttributes(accessControlDn,
          new String[] { "ds-cfg-global-aci" });
      currentAttr = currentAttrs.get("ds-cfg-global-aci");
      // Check what ACIs values must be added or removed
      newAttr = new BasicAttribute("aci");
      newAttr = new BasicAttribute("ds-cfg-global-aci");
      modItem = null;
      if (enable)
      {
@@ -1103,10 +990,11 @@
        }
      }
      // Update the ACI values on the root entry
      // Update the ACI values on the access control entry
      if (modItem != null)
      {
        dirCtx.modifyAttributes("", new ModificationItem[] { modItem});
        dirCtx.modifyAttributes(accessControlDn,
            new ModificationItem[] { modItem});
        result = true;
      }
      else
@@ -1139,7 +1027,22 @@
  private static LdapName makeDNFromHostnameAndPath(String hostname,
      String ipath) throws ADSContextException
  {
    String cnValue = Rdn.escapeValue(hostname + HNP_SEPARATOR + ipath);
    String cnValue = Rdn.escapeValue(hostname + "@" + ipath);
    return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
  }
  /**
   * This method returns the DN of the entry that corresponds to the given host
   * name port representation.
   * @param hostnameport the host name and port.
   * @return the DN of the entry that corresponds to the given host name and
   * port.
   * @throws ADSContextException if something goes wrong.
   */
  private static LdapName makeDNFromHostnamePort(String hostnamePort)
  throws ADSContextException
  {
    String cnValue = Rdn.escapeValue(hostnamePort);
    return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
  }
@@ -1178,8 +1081,16 @@
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    String hostname = getHostname(serverProperties);
    String ipath = getInstallPath(serverProperties);
    return makeDNFromHostnameAndPath(hostname, ipath);
    try
    {
      String ipath = getInstallPath(serverProperties);
      return makeDNFromHostnameAndPath(hostname, ipath);
    }
    catch (ADSContextException ace)
    {
      ServerDescriptor s = ServerDescriptor.createStandalone(serverProperties);
      return makeDNFromHostnamePort(s.getHostPort(true));
    }
  }
  /**
@@ -1213,9 +1124,30 @@
  {
    BasicAttributes attrs = new BasicAttributes();
    String adminPassword = getAdministratorPassword(adminProperties);
    attrs.put("objectclass", "person");
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("person");
    attrs.put(oc);
    attrs.put("sn", "admin");
    attrs.put("userPassword", adminPassword);
    Attribute privilege = new BasicAttribute("ds-privilege-name");
    privilege.add("bypass-acl");
    privilege.add("modify-acl");
    privilege.add("config-read");
    privilege.add("config-write");
    privilege.add("ldif-import");
    privilege.add("ldif-export");
    privilege.add("backend-backup");
    privilege.add("backend-restore");
    privilege.add("server-shutdown");
    privilege.add("server-restart");
    privilege.add("disconnect-client");
    privilege.add("cancel-request");
    privilege.add("password-reset");
    privilege.add("update-schema");
    privilege.add("privilege-change");
    privilege.add("unindexed-search");
    attrs.put(privilege);
    return attrs;
  }
@@ -1241,7 +1173,12 @@
      }
    }
    // Add the objectclass attribute value
    result.put("objectclass", "extensibleobject");
    // TODO: use another structural objectclass
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("ds-cfg-branch");
    oc.add("extensibleobject");
    result.put(oc);
    return result;
  }
@@ -1258,12 +1195,6 @@
    switch(property)
    {
    case HOST_NAME:
      result = null;
      break;
    case INSTANCE_PATH:
      result = null;
      break;
    case GROUPS:
      result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName());
      Iterator groupIterator = ((Set)value).iterator();
@@ -1441,26 +1372,28 @@
        }
        if (prop == null)
        {
          throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED);
        }
        if (attr.size() >= 1 && MULTIVALUED_SERVER_PROPERTIES.contains(prop))
        {
          Set<String> set = new HashSet<String>();
          NamingEnumeration ae = attr.getAll();
          while (ae.hasMore())
          {
            set.add((String)ae.next());
          }
          value = set;
          // Do not handle it
        }
        else
        {
          value = attr.get(0);
        }
        result.put(prop, value);
          if (attr.size() >= 1 && MULTIVALUED_SERVER_PROPERTIES.contains(prop))
          {
            Set<String> set = new HashSet<String>();
            NamingEnumeration ae = attr.getAll();
            while (ae.hasMore())
            {
              set.add((String)ae.next());
            }
            value = set;
          }
          else
          {
            value = attr.get(0);
          }
          result.put(prop, value);
        }
      }
    }
    catch(NamingException x)
@@ -1471,75 +1404,6 @@
    return result;
  }
  /**
   * Returns the properties of a server group for an RDN and some LDAP
   * attributes.
   * @param rdnName the RDN.
   * @param attrs the LDAP attributes.
   * @return the properties of a server group for an RDN and some LDAP
   * attributes.
   * @throws ADSContextException if something goes wrong.
   */
  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String rdnName,
      Attributes attrs) throws ADSContextException
  {
    String hostName, ipath;
    LdapName nameObj;
    nameObj = nameFromDN(rdnName);
    //
    // Extract the hostname and ipath from the dn
    //
    Rdn rdnObj = nameObj.getRdn(nameObj.size() - 1);
    String hostNamePath = (String)Rdn.unescapeValue((String)rdnObj.getValue());
    int sepIndex = hostNamePath.indexOf(HNP_SEPARATOR);
    if (sepIndex != -1)
    {
      hostName = hostNamePath.substring(0, sepIndex);
      ipath = hostNamePath.substring(sepIndex+1, hostNamePath.length());
    }
    else
    { // Emergency logic...
      hostName = hostNamePath;
      ipath = "undefined";
    }
    //
    // Delegate...
    //
    return makePropertiesFromServerAttrs(hostName, ipath, attrs);
  }
  /**
   * Returns the properties of a server for some host name, installation path
   * and LDAP attributes.
   * @param hostName the host name.
   * @param ipath the installation path.
   * @param attrs the LDAP attributes.
   * @return the properties of a server for the given host name, installation
   * path and LDAP attributes.
   * @throws ADSContextException if something goes wrong.
   */
  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String hostName,
      String ipath, Attributes attrs) throws ADSContextException
  {
    Map<ServerProperty, Object> result = new HashMap<ServerProperty, Object>();
    //
    // Put hostname and ipath
    //
    result.put(ServerProperty.HOST_NAME, hostName);
    result.put(ServerProperty.INSTANCE_PATH, ipath);
    //
    // Get other properties from the attributes
    //
    result.putAll(makePropertiesFromServerAttrs(attrs));
    return result;
  }
  /**
   * Returns the properties of an administrator for some rdn and LDAP
@@ -1556,14 +1420,16 @@
  {
    Map<AdministratorProperty, Object> result =
      new HashMap<AdministratorProperty, Object>();
    String dn = rdn + "," + getAdministratorContainerDN();
    LdapName nameObj;
    nameObj = nameFromDN(rdn);
    String dn = nameObj + "," + getAdministratorContainerDN();
    result.put(AdministratorProperty.ADMINISTRATOR_DN, dn);
    try
    {
      NamingEnumeration ne = attrs.getAll();
      NamingEnumeration<? extends Attribute> ne = attrs.getAll();
      while (ne.hasMore()) {
        Attribute attr = (Attribute)ne.next();
        Attribute attr = ne.next();
        String attrID = attr.getID();
        Object value = null;
@@ -1727,6 +1593,7 @@
    }
    catch (InvalidNameException x)
    {
      LOG.log(Level.SEVERE, "Error parsing dn "+dn, x);
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
@@ -1734,6 +1601,32 @@
  }
  /**
   * Returns the String rdn for the given search result name.
   * @return the String rdn for the given search result name.
   * @throws ADSContextException if a valid String rdn could not be retrieved
   * for the given result name.
   */
  private static String getRdn(String rdnName) throws ADSContextException
  {
    CompositeName nameObj;
    String rdn;
    //
    // Transform the JNDI name into a RDN string
    //
    try {
      nameObj = new CompositeName(rdnName);
      rdn = nameObj.get(0);
    }
    catch (InvalidNameException x)
    {
      LOG.log(Level.SEVERE, "Error parsing rdn "+rdnName, x);
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return rdn;
  }
  /**
   * Tells whether an entry with the provided DN exists.
   * @return <CODE>true</CODE> if the entry exists and <CODE>false</CODE> if
   * it does not.
@@ -1777,10 +1670,10 @@
  private void createContainerEntry(String dn) throws ADSContextException
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "top");
    attrs.put("objectclass", "ds-cfg-branch");
    // attrs.put("objectclass", "extensibleobject");
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("ds-cfg-branch");
    attrs.put(oc);
    createEntry(dn, attrs);
  }
@@ -1792,8 +1685,9 @@
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "groupOfUniqueNames");
    attrs.put("objectclass", "groupofurls");
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("groupofurls");
    attrs.put(oc);
    attrs.put("memberURL", "ldap:///" + getAdministratorContainerDN() +
        "??one?(objectclass=*)");
    attrs.put("description", "Group of identities which have full access.");
@@ -1809,9 +1703,10 @@
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "top");
    attrs.put("objectclass", "ds-cfg-branch");
    attrs.put("aci", getTopContainerACI());
    Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("ds-cfg-branch");
    attrs.put(oc);
    createEntry(getAdministrationSuffixDN(), attrs);
  }
@@ -1859,7 +1754,8 @@
  throws ADSContextException
  {
    ADSContextHelper helper = new ADSContextHelper();
    helper.createAdministrationSuffix(getDirContext(), getBackendName());
    helper.createAdministrationSuffix(getDirContext(), getBackendName(),
        "db", "importAdminTemp");
  }
  /**
@@ -1874,7 +1770,7 @@
  private static String getBackendName()
  {
    return "userRoot";
    return "adminRoot";
  }
  /**
@@ -1884,6 +1780,7 @@
  private static String getAdminACI1()
  {
    return
    "(target=\"ldap:///cn=config\")"+
    "(targetattr = \"*\") " +
    "(version 3.0; " +
    "acl \"Enable full access for Global Administrators.\"; " +
@@ -1900,37 +1797,12 @@
  private static String getAdminACI2()
  {
    return
    "(targetattr = \"aci\") (targetscope = \"base\") " +
    "(target=\"ldap:///cn=Access Control Handler,cn=config\")"+
    "(targetattr = \"ds-cfg-global-aci\") (targetscope = \"base\") " +
    "(version 3.0; " +
    "acl \"Enable root ACI modification by Global Administrators.\"; "+
    "acl \"Enable global ACI modification by Global Administrators.\"; "+
    "allow (all)(userdn = \"ldap:///" +
    getAdministratorDN("*") +
    "\");)";
  }
  private static void addToLines(LdapName dn, BasicAttributes attrs,
      LinkedList<String> lines) throws ADSContextException
  {
    lines.add("dn: "+dn.toString());
    NamingEnumeration<String> ids = attrs.getIDs();
    while (ids.hasMoreElements())
    {
      String attrID = ids.nextElement();
      Attribute attr = attrs.get(attrID);
      try
      {
        NamingEnumeration values = attr.getAll();
        while (values.hasMoreElements())
        {
          lines.add(attrID+": "+values.nextElement());
        }
      }
      catch (NamingException ne)
      {
        // This should not happen
        throw new ADSContextException(
            ADSContextException.ErrorType.ERROR_UNEXPECTED, ne);
      }
    }
  }
}
opends/src/ads/org/opends/admin/ads/ADSContextException.java
@@ -96,10 +96,15 @@
     */
    MISSING_ADMIN_UID(ReturnCode.MISSING_ADMIN_UID),
    /**
     * The administratior password is missing.
     * The administrator password is missing.
     */
    MISSING_ADMIN_PASSWORD(ReturnCode.MISSING_ADMIN_PASSWORD),
    /**
     * There is already a backend with the name of the ADS backend but not
     * of the expected type.
     */
    UNEXPECTED_ADS_BACKEND_TYPE(ReturnCode.BROKEN_INSTALL),
    /**
     * Unexpected error (potential bug).
     */
    ERROR_UNEXPECTED(ReturnCode.ERROR_UNEXPECTED);
opends/src/ads/org/opends/admin/ads/ADSContextHelper.java
@@ -115,22 +115,45 @@
   * @param ctx the DirContext to be used.
   * @param backendName the name of the backend where the administration
   * suffix is stored.
   * @param dbDirectory the path of the backend where the administration
   * suffix is stored (will be used if the backend must be created).
   * @param importTempDirectory the path of the backend where the temporary
   * files of import are stored (will be used if the backend must be created).
   * @throws ADSContextException if the administration suffix could not be
   * created.
   */
  public void createAdministrationSuffix(InitialLdapContext ctx,
      String backendName) throws ADSContextException
      String backendName, String dbDirectory, String importTempDirectory)
  throws ADSContextException
  {
    try
    {
      ManagementContext mCtx = LDAPManagementContext.createFromContext(
          JNDIDirContextAdaptor.adapt(ctx));
      RootCfgClient root = mCtx.getRootConfiguration();
      BackendCfgClient backend = root.getBackend(backendName);
      JEBackendCfgClient backend = null;
      try
      {
        backend = (JEBackendCfgClient)root.getBackend(backendName);
      }
      catch (ManagedObjectNotFoundException e)
      {
      }
      catch (ClassCastException cce)
      {
        throw new ADSContextException(
            ADSContextException.ErrorType.UNEXPECTED_ADS_BACKEND_TYPE, cce);
      }
      if (backend == null)
      {
        BackendCfgDefn provider = BackendCfgDefn.getInstance();
        JEBackendCfgDefn provider = JEBackendCfgDefn.getInstance();
        backend = root.createBackend(provider, backendName, null);
        backend.setBackendEnabled(true);
        backend.setBackendId(backendName);
        backend.setBackendDirectory(dbDirectory);
        backend.setBackendImportTempDirectory(importTempDirectory);
        backend.setBackendWritabilityMode(
            BackendCfgDefn.BackendWritabilityMode.ENABLED);
      }
      SortedSet<DN> suffixes = backend.getBackendBaseDN();
      if (suffixes == null)
opends/src/ads/org/opends/admin/ads/DsServiceCliAds.java
@@ -112,7 +112,7 @@
  {
    // Create-ads subcommand
    createAdsSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_ADS
        .toString(), true, 1, 1, OPERAND_BACKEND,
        .toString(), true, 3, 3, OPERAND_BACKEND,
        MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION);
    createAdsSubCmd.setHidden(true);
@@ -144,10 +144,12 @@
    if (subCmd.getName().equals(createAdsSubCmd.getName()))
    {
      String backendName = subCmd.getTrailingArguments().get(0);
      String dbDirectory = subCmd.getTrailingArguments().get(1);
      String importTempDirectory = subCmd.getTrailingArguments().get(2);
      ADSContextHelper helper = new ADSContextHelper();
      adsContext.createAdminData();
      helper.createAdministrationSuffix(adsContext.getDirContext(),
          backendName);
          backendName, dbDirectory, importTempDirectory);
      return ReturnCode.SUCCESSFUL;
    }
    else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
@@ -159,7 +161,7 @@
      return ReturnCode.SUCCESSFUL;
    }
    // Should never occurs: If we are here, it means that the code to
    // Should never occur: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return ReturnCode.ERROR_UNEXPECTED;
  }
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -223,12 +223,15 @@
          ServerProperty.LDAP_ENABLED);
      ArrayList p = (ArrayList)serverProperties.get(
          ServerProperty.LDAP_PORT);
      for (int i=0; i<s.size(); i++)
      if (s != null)
      {
        if (Boolean.TRUE.equals(s.get(i)))
        for (int i=0; i<s.size(); i++)
        {
          port = (Integer)p.get(i);
          break;
          if (Boolean.TRUE.equals(s.get(i)))
          {
            port = (Integer)p.get(i);
            break;
          }
        }
      }
      if (securePreferred)
@@ -236,12 +239,15 @@
        s = (ArrayList)serverProperties.get(
            ServerProperty.LDAPS_ENABLED);
        p = (ArrayList)serverProperties.get(ServerProperty.LDAPS_PORT);
        for (int i=0; i<s.size(); i++)
        if (s != null)
        {
          if (Boolean.TRUE.equals(s.get(i)))
          for (int i=0; i<s.size(); i++)
          {
            port = (Integer)p.get(i);
            break;
            if (Boolean.TRUE.equals(s.get(i)))
            {
              port = (Integer)p.get(i);
              break;
            }
          }
        }
      }
@@ -269,7 +275,7 @@
      {
      }
    }
    return host + "." + port;
    return host + ":" + port;
  }
  /**
@@ -343,6 +349,65 @@
  }
  /**
   * This methods updates the ADS properties (the ones that were read from
   * the ADS) with the contents of the server properties (the ones that were
   * read directly from the server).
   */
  public void updateAdsPropertiesWithServerProperties()
  {
    adsProperties.put(ADSContext.ServerProperty.HOST_NAME, getHostName());
    ServerProperty[][] sProps =
    {
        {ServerProperty.LDAP_ENABLED, ServerProperty.LDAP_PORT},
        {ServerProperty.LDAPS_ENABLED, ServerProperty.LDAPS_PORT},
        {ServerProperty.JMX_ENABLED, ServerProperty.JMX_PORT},
        {ServerProperty.JMXS_ENABLED, ServerProperty.JMXS_PORT}
    };
    ADSContext.ServerProperty[][] adsProps =
    {
        {ADSContext.ServerProperty.LDAP_ENABLED,
          ADSContext.ServerProperty.LDAP_PORT},
        {ADSContext.ServerProperty.LDAPS_ENABLED,
          ADSContext.ServerProperty.LDAPS_PORT},
        {ADSContext.ServerProperty.JMX_ENABLED,
          ADSContext.ServerProperty.JMX_PORT},
        {ADSContext.ServerProperty.JMXS_ENABLED,
          ADSContext.ServerProperty.JMXS_PORT}
    };
    for (int i=0; i<sProps.length; i++)
    {
      ArrayList s = (ArrayList)serverProperties.get(sProps[i][0]);
      ArrayList p = (ArrayList)serverProperties.get(sProps[i][1]);
      if (s != null)
      {
        int port = -1;
        for (int j=0; j<s.size(); i++)
        {
          if (Boolean.TRUE.equals(s.get(j)))
          {
            port = (Integer)p.get(j);
            break;
          }
        }
        if (port == -1)
        {
          adsProperties.put(adsProps[i][0], "false");
          if (p.size() > 0)
          {
            port = (Integer)p.iterator().next();
          }
        }
        else
        {
          adsProperties.put(adsProps[i][0], "true");
        }
        adsProperties.put(adsProps[i][1], String.valueOf(port));
      }
    }
  }
  /**
   * Creates a ServerDescriptor object based on some ADS properties provided.
   * @param adsProperties the ADS properties of the server.
   * @return a ServerDescriptor object that corresponds to the provided ADS
@@ -522,17 +587,18 @@
        int nEntries = getEntryCount(ctx, id);
        Set<ReplicaDescriptor> replicas = desc.getReplicas();
        for (String baseDn : baseDns)
        {
          SuffixDescriptor suffix = new SuffixDescriptor();
          suffix.setDN(baseDn);
          ReplicaDescriptor replica = new ReplicaDescriptor();
          replica.setServer(desc);
          Set<ReplicaDescriptor> replicas = new HashSet<ReplicaDescriptor>();
          replicas.add(replica);
          suffix.setReplicas(replicas);
          HashSet<ReplicaDescriptor> r = new HashSet<ReplicaDescriptor>();
          r.add(replica);
          suffix.setReplicas(r);
          replica.setSuffix(suffix);
          desc.setReplicas(replicas);
          if (baseDns.size() == 1)
          {
            replica.setEntries(nEntries);
@@ -543,6 +609,7 @@
            replica.setEntries(-1);
          }
        }
        desc.setReplicas(replicas);
      }
    }
  }
opends/src/ads/org/opends/admin/ads/TopologyCache.java
@@ -136,6 +136,9 @@
        ServerDescriptor descriptor = loader.getServerDescriptor();
        for (ReplicaDescriptor replica : descriptor.getReplicas())
        {
          LOG.log(Level.INFO, "Handling replica with dn: "+
              replica.getSuffix().getDN());
          boolean suffixFound = false;
          LdapName dn = new LdapName(replica.getSuffix().getDN());
          Set<SuffixDescriptor> sufs = hmSuffixes.get(dn);
opends/src/ads/org/opends/admin/ads/TopologyCacheException.java
@@ -65,6 +65,10 @@
     */
    NOT_GLOBAL_ADMINISTRATOR,
    /**
     * Not enough permissions to read the server configuration.
     */
    NO_PERMISSIONS,
    /**
     * Timeout reading the configuration of a particular server.
     */
    TIMEOUT,
opends/src/ads/org/opends/admin/ads/util/ApplicationTrustManager.java
@@ -78,7 +78,7 @@
  private X509TrustManager sunJSSEX509TrustManager;
  private String lastRefusedAuthType;
  private X509Certificate[] lastRefusedChain;
  private Cause lastRefusedCause;
  private Cause lastRefusedCause = null;
  /*
   * The following ArrayList contain information about the certificates
opends/src/ads/org/opends/admin/ads/util/ServerLoader.java
@@ -31,6 +31,7 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.AuthenticationException;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.ldap.InitialLdapContext;
@@ -148,6 +149,31 @@
                TopologyCacheException.Type.NOT_GLOBAL_ADMINISTRATOR, npe,
                trustManager, getLastLdapUrl());
      }
      else
      {
        lastException =
          new TopologyCacheException(
              TopologyCacheException.Type.NO_PERMISSIONS, npe,
              trustManager, getLastLdapUrl());
      }
    }
    catch (AuthenticationException ae)
    {
      LOG.log(Level.WARNING,
          "Authentication exception: "+getLastLdapUrl(), ae);
      if (!isAdministratorDn())
      {
        lastException = new TopologyCacheException(
                TopologyCacheException.Type.NOT_GLOBAL_ADMINISTRATOR, ae,
                trustManager, getLastLdapUrl());
      }
      else
      {
        lastException =
          new TopologyCacheException(
              TopologyCacheException.Type.GENERIC_READING_SERVER, ae,
              trustManager, getLastLdapUrl());
      }
    }
    catch (NamingException ne)
    {
@@ -174,6 +200,7 @@
      {
        LOG.log(Level.WARNING,
            "Generic error reading server: "+getLastLdapUrl(), t);
        LOG.log(Level.WARNING, "server Properties: "+serverProperties);
        lastException =
            new TopologyCacheException(TopologyCacheException.Type.BUG, t);
      }
@@ -338,7 +365,7 @@
      LdapName theDn = new LdapName(dn);
      LdapName containerDn =
        new LdapName(ADSContext.getAdministratorContainerDN());
      isAdministratorDn = theDn.endsWith(containerDn);
      isAdministratorDn = theDn.startsWith(containerDn);
    }
    catch (Throwable t)
    {