>From 09484bf1d9103a43dc797a3769f6cd19c8db5035 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Wed, 21 Mar 2012 23:25:29 -0400
Subject: [PATCH] Allow clones to specify master and replica ports and
 security options

Removed -clone_start_tls option and subsumed it into -replicationSecurity.
Refactored DatabasePanel parameter verification code to allow it to be
used in both update() and validate().  Added new parameters to pkisilent
and databasepanel.vm.

Also fixed cloning error when master uses localhost.
---
 .../src/com/netscape/certsrv/util/HttpInput.java   |   42 +---
 .../cms/servlet/csadmin/ConfigHSMLoginPanel.java   |   16 +--
 .../cms/servlet/csadmin/DatabasePanel.java         |  249 ++++++++++++--------
 .../cms/servlet/csadmin/GetConfigEntries.java      |    7 +-
 .../src/com/netscape/pkisilent/ConfigureCA.java    |   41 ++-
 .../src/com/netscape/pkisilent/ConfigureDRM.java   |   44 +++--
 .../shared/admin/console/config/databasepanel.vm   |   47 +++-
 7 files changed, 261 insertions(+), 185 deletions(-)

diff --git a/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java b/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java
index fba601b6c61c580c10556de345ce520d8b51f48a..ba5bfdb08e4e051051a8d4de2a06b711633b1845 100644
--- a/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java
+++ b/pki/base/common/src/com/netscape/certsrv/util/HttpInput.java
@@ -86,8 +86,7 @@ public class HttpInput {
         return v;
     }
 
-    public static String getString(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getString(HttpServletRequest request, String name) {
         String val = request.getParameter(name);
         return val;
     }
@@ -102,8 +101,7 @@ public class HttpInput {
         return val;
     }
 
-    public static String getLdapDatabase(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getLdapDatabase(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
@@ -118,13 +116,11 @@ public class HttpInput {
         return v;
     }
 
-    public static String getUID(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getUID(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getPassword(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getPassword(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
@@ -199,48 +195,39 @@ public class HttpInput {
         return v;
     }
 
-    public static String getID(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getID(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getName(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getName(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getCertRequest(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getCertRequest(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getCertChain(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getCertChain(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getCert(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getCert(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getNickname(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getNickname(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getHostname(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getHostname(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getTokenName(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getTokenName(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
-    public static String getReplicationAgreementName(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getReplicationAgreementName(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
@@ -253,8 +240,7 @@ public class HttpInput {
         return v;
     }
 
-    public static String getDomainName(HttpServletRequest request, String name)
-            throws IOException {
+    public static String getDomainName(HttpServletRequest request, String name) {
         return getString(request, name);
     }
 
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
index 92e2ee392f717748123d5bd610f5f2d67d07fb6b..03233042c89b77d6624a903c133555601deeca6b 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/ConfigHSMLoginPanel.java
@@ -32,7 +32,6 @@ import org.mozilla.jss.util.IncorrectPasswordException;
 import org.mozilla.jss.util.Password;
 
 import com.netscape.certsrv.apps.CMS;
-import com.netscape.certsrv.base.IConfigStore;
 import com.netscape.certsrv.property.Descriptor;
 import com.netscape.certsrv.property.IDescriptor;
 import com.netscape.certsrv.property.PropertySet;
@@ -97,10 +96,7 @@ public class ConfigHSMLoginPanel extends WizardPanelBase {
 
         // get token selected to be logged in
         String tokName = null;
-        try {
-            tokName = HttpInput.getTokenName(request, "SecToken");
-        } catch (IOException e) {
-        }
+        tokName = HttpInput.getTokenName(request, "SecToken");
 
         if (tokName != null) {
             CMS.debug("ConfigHSMLoginPanel: selected token name= " + tokName);
@@ -214,16 +210,6 @@ public class ConfigHSMLoginPanel extends WizardPanelBase {
             HttpServletResponse response,
             Context context) {
 
-        IConfigStore cs = CMS.getConfigStore();
-        String select = "";
-        try {
-            select = cs.getString("preop.subsystem.select", "");
-        } catch (Exception e) {
-        }
-
-        //        if (select.equals("clone"))
-        //           return;
-
         CMS.debug("ConfigHSMLoginPanel: in update()");
 
         String uTokName = null;
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
index d3b0e380ec14f49bf0b0ceb4daee54b776e8fe69..82c45d1cdd020ca355a7f5edbf1681b77cd12b34 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java
@@ -67,11 +67,7 @@ public class DatabasePanel extends WizardPanelBase {
     private static final String HOST = "localhost";
     private static final String CLONE_HOST = "Enter FQDN here";
     private static final String PORT = "389";
-    private static final String BASEDN = "o=netscapeCertificateServer";
     private static final String BINDDN = "cn=Directory Manager";
-    private static final String DATABASE = "csRoot";
-    private static final String MASTER_AGREEMENT = "masteragreement-";
-    private static final String CLONE_AGREEMENT = "cloneagreement-";
 
     private WizardServlet mServlet = null;
 
@@ -170,7 +166,10 @@ public class DatabasePanel extends WizardPanelBase {
         String database = null;
         String errorString = "";
         String secure = "false";
-        String cloneStartTLS = "false";
+        String masterReplicationPort = "";
+        String cloneReplicationPort = "";
+        String replicationSecurity = "";
+
         try {
             @SuppressWarnings("unused")
             String s = cs.getString("preop.database.removeData"); // check whether it's first time
@@ -192,7 +191,9 @@ public class DatabasePanel extends WizardPanelBase {
                 binddn = cs.getString("internaldb.ldapauth.bindDN", "");
                 database = cs.getString("internaldb.database", "");
                 secure = cs.getString("internaldb.ldapconn.secureConn", "");
-                cloneStartTLS = cs.getString("internaldb.ldapconn.cloneStartTLS", "");
+                replicationSecurity = cs.getString("internaldb.ldapconn.replicationSecurity", "None");
+                masterReplicationPort = cs.getString("internaldb.ldapconn.masterReplicationPort", "");
+                cloneReplicationPort = cs.getString("internaldb.ldapconn.cloneReplicationPort", "");
                 errorString = cs.getString("preop.database.errorString", "");
             } catch (Exception e) {
                 CMS.debug("DatabasePanel display: " + e.toString());
@@ -247,7 +248,9 @@ public class DatabasePanel extends WizardPanelBase {
         context.put("bindpwd", bindpwd);
         context.put("database", database);
         context.put("secureConn", (secure.equals("true") ? "on" : "off"));
-        context.put("cloneStartTLS", (cloneStartTLS.equals("true") ? "on" : "off"));
+        context.put("masterReplicationPort", masterReplicationPort);
+        context.put("cloneReplicationPort", cloneReplicationPort);
+        context.put("replicationSecurity", replicationSecurity);
         context.put("panel", "admin/console/config/databasepanel.vm");
         context.put("errorString", errorString);
     }
@@ -261,134 +264,144 @@ public class DatabasePanel extends WizardPanelBase {
         } catch (Exception e) {
         }
         context.put("clone", select);
-        context.put("hostname", request.getParameter("host"));
-        context.put("portStr", request.getParameter("port"));
-        context.put("basedn", request.getParameter("basedn"));
-        context.put("binddn", request.getParameter("binddn"));
-        context.put("bindpwd", request.getParameter("__bindpwd"));
-        context.put("database", request.getParameter("database"));
+        context.put("hostname", (request.getParameter("host") != null) ? request.getParameter("host") : "");
+        context.put("portStr", (request.getParameter("port") != null) ? request.getParameter("port") : "");
+        context.put("basedn", (request.getParameter("basedn") != null) ? request.getParameter("basedn") : "");
+        context.put("binddn", (request.getParameter("binddn") != null) ? request.getParameter("binddn") : "");
+        context.put("bindpwd", (request.getParameter("__bindpwd") != null) ?
+                request.getParameter("__bindpwd"): "");
+        context.put("database", (request.getParameter("database") != null) ?
+                request.getParameter("database") : "");
+        context.put("masterReplicationPort", (request.getParameter("masterReplicationPort") != null) ?
+                request.getParameter("masterReplicationPort"): "");
+        context.put("cloneReplicationPort", (request.getParameter("cloneReplicationPort") != null) ?
+                request.getParameter("cloneReplicationPort"): "");
+        context.put("replicationSecurity", (request.getParameter("replicationSecurity") != null) ?
+                request.getParameter("replicationSecurity"): "None");
     }
 
     /**
-     * Checks if the given parameters are valid.
+     * Parses and validates the parameters in the request.
      */
-    public void validate(HttpServletRequest request,
-            HttpServletResponse response,
-            Context context) throws IOException {
-
+    public void parseParameters(HttpServletRequest request,
+            HttpServletResponse response, Context context) throws IOException {
         IConfigStore cs = CMS.getConfigStore();
-        context.put("firsttime", "false");
+
+        String select = "";
         try {
-            @SuppressWarnings("unused")
-            String s = cs.getString("preop.database.removeData"); // check whether it's first time
+            select = cs.getString("preop.subsystem.select", "");
         } catch (Exception e) {
-            context.put("firsttime", "true");
         }
 
         String hostname = HttpInput.getHostname(request, "host");
+        if (hostname == null || hostname.length() == 0) {
+            throw new IOException("hostname is empty string");
+        }
         context.put("hostname", hostname);
 
+        // this validates that port is an integer
         String portStr = HttpInput.getPortNumber(request, "port");
         context.put("portStr", portStr);
 
         String basedn = HttpInput.getDN(request, "basedn");
+        if (basedn == null || basedn.length() == 0) {
+            throw new IOException("basedn is empty string");
+        }
         context.put("basedn", basedn);
 
         String binddn = HttpInput.getDN(request, "binddn");
+        if (binddn == null || binddn.length() == 0) {
+            throw new IOException("binddn is empty string");
+        }
         context.put("binddn", binddn);
 
         String database = HttpInput.getLdapDatabase(request, "database");
+        if (database == null || database.length() == 0) {
+            throw new IOException("Database is empty string");
+        }
         context.put("database", database);
 
         String bindpwd = HttpInput.getPassword(request, "__bindpwd");
+        if (bindpwd == null || bindpwd.length() == 0) {
+            throw new IOException("Bind password is empty string");
+        }
         context.put("bindpwd", bindpwd);
 
         String secure = HttpInput.getCheckbox(request, "secureConn");
         context.put("secureConn", secure);
 
-        String cloneStartTLS = HttpInput.getCheckbox(request, "cloneStartTLS");
-        context.put("cloneStartTLS", cloneStartTLS);
+        String masterReplicationPort = HttpInput.getString(request, "masterReplicationPort");
+        if (masterReplicationPort != null && masterReplicationPort.length() > 0) {
+            try {
+                Integer.parseInt(masterReplicationPort); // check for errors
+            } catch (NumberFormatException e) {
+                throw new IOException("Master replication port is invalid");
+            }
+        }
+        context.put("masterReplicationPort", masterReplicationPort);
 
-        String select = "";
-        try {
-            select = cs.getString("preop.subsystem.select", "");
-        } catch (Exception e) {
+        String cloneReplicationPort = HttpInput.getString(request, "cloneReplicationPort");
+        if (cloneReplicationPort != null && cloneReplicationPort.length() > 0) {
+            try {
+                Integer.parseInt(cloneReplicationPort); // check for errors
+            } catch (Exception e) {
+                throw new IOException("Clone replication port is invalid");
+            }
         }
+        context.put("cloneReplicationPort", cloneReplicationPort);
+
+        String replicationSecurity = HttpInput.getString(request, "replicationSecurity");
+        context.put("replicationSecurity", replicationSecurity);
 
         if (select.equals("clone")) {
             String masterhost = "";
             String masterport = "";
             String masterbasedn = "";
+            String realhostname = "";
             try {
                 masterhost = cs.getString("preop.internaldb.master.ldapconn.host", "");
                 masterport = cs.getString("preop.internaldb.master.ldapconn.port", "");
                 masterbasedn = cs.getString("preop.internaldb.master.basedn", "");
+                realhostname = cs.getString("machineName", "");
             } catch (Exception e) {
             }
 
-            //get the real host name
-            String realhostname = "";
-            if (hostname.equals("localhost")) {
-                try {
-                    realhostname = cs.getString("machineName", "");
-                } catch (Exception ee) {
-                }
-            }
             if (masterhost.equals(realhostname) && masterport.equals(portStr)) {
-                context.put("updateStatus", "validate-failure");
                 throw new IOException("Master and clone must not share the same internal database");
             }
 
             if (!masterbasedn.equals(basedn)) {
-                context.put("updateStatus", "validate-failure");
                 throw new IOException("Master and clone should have the same base DN");
             }
         }
 
-        if (hostname == null || hostname.length() == 0) {
-            cs.putString("preop.database.errorString", "Host is empty string");
-            context.put("updateStatus", "validate-failure");
-            throw new IOException("Host is empty string");
-        }
+        context.put("errorString", "");
+        cs.putString("preop.database.errorString", "");
+    }
 
-        if (portStr != null && portStr.length() > 0) {
-            try {
-                Integer.parseInt(portStr); // check for errors
-            } catch (Exception e) {
-                cs.putString("preop.database.errorString", "Port is invalid");
-                context.put("updateStatus", "validate-failure");
-                throw new IOException("Port is invalid");
-            }
-        } else {
-            cs.putString("preop.database.errorString", "Port is empty string");
-            context.put("updateStatus", "validate-failure");
-            throw new IOException("Port is empty string");
-        }
+    /**
+     * Checks if the given parameters are valid.
+     */
+    public void validate(HttpServletRequest request,
+            HttpServletResponse response,
+            Context context) throws IOException {
 
-        if (basedn == null || basedn.length() == 0) {
-            cs.putString("preop.database.errorString", "Base DN is empty string");
-            context.put("updateStatus", "validate-failure");
-            throw new IOException("Base DN is empty string");
-        }
-
-        if (binddn == null || binddn.length() == 0) {
-            cs.putString("preop.database.errorString", "Bind DN is empty string");
-            context.put("updateStatus", "validate-failure");
-            throw new IOException("Bind DN is empty string");
-        }
-
-        if (database == null || database.length() == 0) {
-            cs.putString("preop.database.errorString",
-                    "Database is empty string");
-            context.put("updateStatus", "validate-failure");
-            throw new IOException("Database is empty string");
+        IConfigStore cs = CMS.getConfigStore();
+        context.put("firsttime", "false");
+        try {
+            @SuppressWarnings("unused")
+            String s = cs.getString("preop.database.removeData"); // check whether it's first time
+        } catch (Exception e) {
+            context.put("firsttime", "true");
         }
 
-        if (bindpwd == null || bindpwd.length() == 0) {
-            cs.putString("preop.database.errorString",
-                    "Bind password is empty string");
+        try {
+            parseParameters(request, response, context);
+        } catch (IOException e) {
+            context.put("errorString", e.getMessage());
+            cs.putString("preop.database.errorString", e.getMessage());
             context.put("updateStatus", "validate-failure");
-            throw new IOException("Bind password is empty string");
+            throw e;
         }
 
         context.put("errorString", "");
@@ -737,8 +750,6 @@ public class DatabasePanel extends WizardPanelBase {
         } else {
             // data will be replicated from the master to the clone
             // so clone does not need the data
-            //
-
             importLDIFS("preop.internaldb.schema.ldif", conn);
             importLDIFS("preop.internaldb.ldif", conn);
             importLDIFS("preop.internaldb.data_ldif", conn);
@@ -885,6 +896,7 @@ public class DatabasePanel extends WizardPanelBase {
         }
     }
 
+
     /**
      * Commit parameter changes
      */
@@ -905,29 +917,63 @@ public class DatabasePanel extends WizardPanelBase {
         String hostname1 = "";
         String portStr1 = "";
         String database1 = "";
+        String masterPortStr = "";
 
         try {
             hostname1 = cs.getString("internaldb.ldapconn.host", "");
             portStr1 = cs.getString("internaldb.ldapconn.port", "");
             database1 = cs.getString("internaldb.database", "");
+            masterPortStr = cs.getString("preop.internaldb.master.ldapconn.port", "0");
         } catch (Exception e) {
         }
 
-        String hostname2 = HttpInput.getHostname(request, "host");
-        String portStr2 = HttpInput.getPortNumber(request, "port");
-        String database2 = HttpInput.getLdapDatabase(request, "database");
-        String basedn2 = HttpInput.getDN(request, "basedn");
+        try {
+            parseParameters(request, response, context);
+        } catch (IOException e) {
+            context.put("errorString", e.getMessage());
+            cs.putString("preop.database.errorString", e.getMessage());
+            context.put("updateStatus", "validate-failure");
+            throw e;
+        }
+
+        String hostname2 = (String) context.get("hostname");
+        String portStr2 = (String) context.get("portStr");
+        String database2 = (String) context.get("database");
+        String basedn2 = (String) context.get("basedn");
+        String binddn = (String) context.get("binddn");
+        String secure = (String) context.get("secureConn");
+        String masterReplicationPortStr = (String) context.get("masterReplicationPort");
+        String cloneReplicationPortStr = (String) context.get("cloneReplicationPort");
 
         cs.putString("internaldb.ldapconn.host", hostname2);
         cs.putString("internaldb.ldapconn.port", portStr2);
+        cs.putString("internaldb.database", database2);
         cs.putString("internaldb.basedn", basedn2);
-        String binddn = HttpInput.getDN(request, "binddn");
         cs.putString("internaldb.ldapauth.bindDN", binddn);
-        cs.putString("internaldb.database", database2);
-        String secure = HttpInput.getCheckbox(request, "secureConn");
         cs.putString("internaldb.ldapconn.secureConn", (secure.equals("on") ? "true" : "false"));
-        String cloneStartTLS = HttpInput.getCheckbox(request, "cloneStartTLS");
-        cs.putString("internaldb.ldapconn.cloneStartTLS", (cloneStartTLS.equals("on") ? "true" : "false"));
+
+        int masterReplicationPort = 0;
+        if ((masterReplicationPortStr == null) || (masterReplicationPortStr.length() == 0)) {
+            masterReplicationPortStr = masterPortStr;
+        }
+        masterReplicationPort = Integer.parseInt(masterReplicationPortStr);
+        cs.putString("internaldb.ldapconn.masterReplicationPort", masterReplicationPortStr);
+
+        int cloneReplicationPort = 0;
+        int port = Integer.parseInt(portStr2);
+        if ((cloneReplicationPortStr == null) || (cloneReplicationPortStr.length() == 0)) {
+            cloneReplicationPortStr = portStr2;
+        }
+        cloneReplicationPort = Integer.parseInt(cloneReplicationPortStr);
+        cs.putString("internaldb.ldapconn.cloneReplicationPort", cloneReplicationPortStr);
+
+        String replicationSecurity = HttpInput.getString(request, "replicationSecurity");
+        if ((cloneReplicationPort == port) && (secure.equals("true"))) {
+            replicationSecurity = "SSL";
+        } else if (replicationSecurity == null) {
+            replicationSecurity = "None";
+        }
+        cs.putString("internaldb.ldapconn.replicationSecurity", replicationSecurity);
 
         String remove = HttpInput.getID(request, "removeData");
         if (isPanelDone() && (remove == null || remove.equals(""))) {
@@ -1054,8 +1100,8 @@ public class DatabasePanel extends WizardPanelBase {
         // setup replication after indexes have been created
         if (select.equals("clone")) {
             CMS.debug("Start setting up replication.");
-            setupReplication(request, context, (secure.equals("on") ? "true" : "false"), (cloneStartTLS.equals("on")
-                    ? "true" : "false"));
+            setupReplication(request, context, (secure.equals("on") ? "true" : "false"),
+                    replicationSecurity, masterReplicationPort, cloneReplicationPort);
             CMS.debug("Finish setting up replication.");
 
             try {
@@ -1084,7 +1130,9 @@ public class DatabasePanel extends WizardPanelBase {
     }
 
     private void setupReplication(HttpServletRequest request,
-                  Context context, String secure, String cloneStartTLS) throws IOException {
+                  Context context, String secure, String replicationSecurity,
+                  int masterReplicationPort, int cloneReplicationPort)
+            throws IOException {
         IConfigStore cs = CMS.getConfigStore();
 
         String cstype = "";
@@ -1138,18 +1186,14 @@ public class DatabasePanel extends WizardPanelBase {
         }
 
         String master_hostname = "";
-        int master_port = -1;
         String master_replicationpwd = "";
         String replica_hostname = "";
-        int replica_port = -1;
         String replica_replicationpwd = "";
 
         try {
             master_hostname = cs.getString("preop.internaldb.master.ldapconn.host", "");
-            master_port = cs.getInteger("preop.internaldb.master.ldapconn.port", -1);
             master_replicationpwd = cs.getString("preop.internaldb.master.replication.password", "");
             replica_hostname = cs.getString("internaldb.ldapconn.host", "");
-            replica_port = cs.getInteger("internaldb.ldapconn.port", -1);
             replica_replicationpwd = cs.getString("preop.internaldb.replicationpwd", "");
         } catch (Exception e) {
         }
@@ -1187,12 +1231,12 @@ public class DatabasePanel extends WizardPanelBase {
             CMS.debug("DatabasePanel setupReplication: Finished enabling replication");
 
             createReplicationAgreement(replicadn, masterConn, masterAgreementName,
-                    replica_hostname, replica_port, replica_replicationpwd, basedn, cloneBindUser, secure,
-                    cloneStartTLS);
+                    replica_hostname, cloneReplicationPort, replica_replicationpwd, basedn,
+                    cloneBindUser, secure, replicationSecurity);
 
             createReplicationAgreement(replicadn, replicaConn, cloneAgreementName,
-                    master_hostname, master_port, master_replicationpwd, basedn, masterBindUser, secure,
-                    cloneStartTLS);
+                    master_hostname, masterReplicationPort, master_replicationpwd, basedn,
+                    masterBindUser, secure, replicationSecurity);
 
             // initialize consumer
             initializeConsumer(replicadn, masterConn, masterAgreementName);
@@ -1353,7 +1397,7 @@ public class DatabasePanel extends WizardPanelBase {
 
     private void createReplicationAgreement(String replicadn,
             LDAPConnection conn, String name, String replicahost, int replicaport,
-            String replicapwd, String basedn, String bindUser, String secure, String cloneStartTLS)
+            String replicapwd, String basedn, String bindUser, String secure, String replicationSecurity)
             throws LDAPException {
         String dn = "cn=" + name + "," + replicadn;
         CMS.debug("DatabasePanel createReplicationAgreement: dn: " + dn);
@@ -1367,15 +1411,16 @@ public class DatabasePanel extends WizardPanelBase {
             attrs.add(new LDAPAttribute("cn", name));
             attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn));
             attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost));
+
             attrs.add(new LDAPAttribute("nsDS5ReplicaPort", "" + replicaport));
             attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN",
                     "cn=" + bindUser + ",ou=csusers,cn=config"));
             attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple"));
             attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd));
 
-            if (secure.equals("true")) {
+            if (replicationSecurity.equals("SSL")) {
                 attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "SSL"));
-            } else if (cloneStartTLS.equals("true")) {
+            } else if (replicationSecurity.equals("TLS")) {
                 attrs.add(new LDAPAttribute("nsDS5ReplicaTransportInfo", "TLS"));
             }
 
diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
index f1a35bac5fb95a3d17de2dd4fa71e1907da478dd..33d82e9b88e3117fa2c7be58393c352da67bc0f5 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/GetConfigEntries.java
@@ -18,6 +18,7 @@
 package com.netscape.cms.servlet.csadmin;
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.util.Enumeration;
 import java.util.Locale;
 import java.util.StringTokenizer;
@@ -50,7 +51,6 @@ public class GetConfigEntries extends CMSServlet {
      */
     private static final long serialVersionUID = -7418561215631752315L;
     private final static String SUCCESS = "0";
-    private final static String FAILED = "1";
     private final static String AUTH_FAILURE = "2";
 
     public GetConfigEntries() {
@@ -146,6 +146,9 @@ public class GetConfigEntries extends CMSServlet {
                     String name = name1 + "." + enum1.nextElement();
                     try {
                         String value = config.getString(name);
+                        if (value.equals("localhost")) {
+                            value = config.getString("machineName", InetAddress.getLocalHost().getHostName());
+                        }
                         Node container = xmlObj.createContainer(root, "Config");
                         xmlObj.addItemToContainer(container, "name", name);
                         xmlObj.addItemToContainer(container, "value", value);
@@ -166,7 +169,7 @@ public class GetConfigEntries extends CMSServlet {
                     value = config.getString(name);
                     CMS.debug("Retrieving config value=" + value);
                     if (value.equals("localhost"))
-                        value = config.getString("machineName", "");
+                        value = config.getString("machineName", InetAddress.getLocalHost().getHostName());
                 } catch (Exception ee) {
                     if (name.equals("internaldb.ldapauth.password")) {
                         value = getLDAPPassword();
diff --git a/pki/base/silent/src/com/netscape/pkisilent/ConfigureCA.java b/pki/base/silent/src/com/netscape/pkisilent/ConfigureCA.java
index 84fe0342f617d491b89f4ff2215583ec473d7aaa..3c498febe9c6a2182bef22cb84c9f6a996e82c3b 100644
--- a/pki/base/silent/src/com/netscape/pkisilent/ConfigureCA.java
+++ b/pki/base/silent/src/com/netscape/pkisilent/ConfigureCA.java
@@ -93,7 +93,6 @@ public class ConfigureCA {
     public static String base_dn = null;
     public static String db_name = null;
     public static String secure_conn = null;
-    public static String clone_start_tls = null;
     public static String remove_data = null;
 
     public static String key_type = null;
@@ -179,6 +178,9 @@ public class ConfigureCA {
     public static String clone_uri = null;
     public static String clone_p12_passwd = null;
     public static String clone_p12_file = null;
+    public static String clone_master_port = null;
+    public static String clone_replica_port = null;
+    public static String clone_replication_security = null;
 
     //for correct selection of CA to be cloned
     public static String urls;
@@ -477,15 +479,17 @@ public class ConfigureCA {
             HTTPResponse hr = null;
 
             String query_string = "p=9" + "&op=next" + "&xml=true" + "&host="
-                    + URLEncoder.encode(ldap_host) + "&port="
-                    + URLEncoder.encode(ldap_port) + "&binddn="
-                    + URLEncoder.encode(bind_dn) + "&__bindpwd="
-                    + URLEncoder.encode(bind_password) + "&basedn="
-                    + URLEncoder.encode(base_dn) + "&database="
-                    + URLEncoder.encode(db_name) + "&display="
-                    + URLEncoder.encode("$displayStr")
+                    + URLEncoder.encode(ldap_host,"UTF-8") + "&port="
+                    + URLEncoder.encode(ldap_port,"UTF-8") + "&binddn="
+                    + URLEncoder.encode(bind_dn, "UTF-8") + "&__bindpwd="
+                    + URLEncoder.encode(bind_password, "UTF-8") + "&basedn="
+                    + URLEncoder.encode(base_dn, "UTF-8") + "&database="
+                    + URLEncoder.encode(db_name, "UTF-8") + "&display="
+                    + URLEncoder.encode("$displayStr", "UTF-8")
                     + (secure_conn.equals("true") ? "&secureConn=on" : "")
-                    + (clone_start_tls.equals("true") ? "&cloneStartTLS=on" : "")
+                    + "&masterReplicationPort=" + URLEncoder.encode(clone_master_port, "UTF-8")
+                    + "&cloneReplicationPort=" + URLEncoder.encode(clone_replica_port, "UTF-8")
+                    + "&replicationSecurity=" + URLEncoder.encode(clone_replication_security, "UTF-8")
                     + (remove_data.equals("true") ? "&removeData=true" : "");
 
             hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
@@ -1335,7 +1339,6 @@ public class ConfigureCA {
         StringHolder x_base_dn = new StringHolder();
         StringHolder x_db_name = new StringHolder();
         StringHolder x_secure_conn = new StringHolder();
-        StringHolder x_clone_start_tls = new StringHolder();
         StringHolder x_remove_data = new StringHolder();
 
         // key properties (defaults)
@@ -1406,6 +1409,9 @@ public class ConfigureCA {
         StringHolder x_clone_uri = new StringHolder();
         StringHolder x_clone_p12_file = new StringHolder();
         StringHolder x_clone_p12_passwd = new StringHolder();
+        StringHolder x_clone_master_port = new StringHolder();
+        StringHolder x_clone_replica_port = new StringHolder();
+        StringHolder x_clone_replication_security = new StringHolder();
 
         //security domain
         StringHolder x_sd_hostname = new StringHolder();
@@ -1447,9 +1453,6 @@ public class ConfigureCA {
         parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
         parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
                 x_remove_data);
-        parser.addOption(
-                "-clone_start_tls %s #use startTLS for cloning replication agreement (optional, default is false)",
-                x_clone_start_tls);
 
         // key and algorithm options (default)
         parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
@@ -1554,6 +1557,14 @@ public class ConfigureCA {
         parser.addOption("-clone_p12_password %s #Password for pk12 file (optional, required if -clone=true)",
                 x_clone_p12_passwd);
 
+        // replication agreement options
+        parser.addOption("-clone_master_port %s #Master Port to be used in replication agreement (optional)",
+                x_clone_master_port);
+        parser.addOption("-clone_replica_port %s #Replica Port to be used in replication agreement (optional)",
+                x_clone_replica_port);
+        parser.addOption("-clone_replication_security %s #Type of security in replication agreement (optional)",
+                x_clone_replication_security);
+
         parser.addOption("-sd_hostname %s #Security Domain Hostname (optional, required if -clone=true)", x_sd_hostname);
         parser.addOption("-sd_ssl_port %s #Security Domain SSL EE port (optional, required if -clone=true)",
                 x_sd_ssl_port);
@@ -1598,7 +1609,6 @@ public class ConfigureCA {
         db_name = x_db_name.value;
         secure_conn = set_default(x_secure_conn.value, "false");
         remove_data = set_default(x_remove_data.value, "false");
-        clone_start_tls = set_default(x_clone_start_tls.value, "false");
 
         key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
         signing_key_type = set_default(x_signing_key_type.value, key_type);
@@ -1662,6 +1672,9 @@ public class ConfigureCA {
         clone_uri = x_clone_uri.value;
         clone_p12_file = x_clone_p12_file.value;
         clone_p12_passwd = x_clone_p12_passwd.value;
+        clone_master_port = set_default(x_clone_master_port.value, "");
+        clone_replica_port = set_default(x_clone_replica_port.value, "");
+        clone_replication_security = set_default(x_clone_replication_security.value, "None");
 
         sd_hostname = x_sd_hostname.value;
         sd_ssl_port = x_sd_ssl_port.value;
diff --git a/pki/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java b/pki/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java
index d38c92236aed8333c79de0972fc420db2bcd00e9..7d548ddf3cf0e75d1cdc10d8fb7e223c67b7eb56 100644
--- a/pki/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java
+++ b/pki/base/silent/src/com/netscape/pkisilent/ConfigureDRM.java
@@ -96,7 +96,6 @@ public class ConfigureDRM {
     public static String base_dn = null;
     public static String db_name = null;
     public static String secure_conn = null;
-    public static String clone_start_tls = null;
     public static String remove_data = null;
 
     public static String key_type = null;
@@ -174,6 +173,9 @@ public class ConfigureDRM {
     public static String clone_uri = null;
     public static String clone_p12_passwd = null;
     public static String clone_p12_file = null;
+    public static String clone_master_port = null;
+    public static String clone_replica_port = null;
+    public static String clone_replication_security = null;
 
     //for correct selection of CA to be cloned
     public static String urls;
@@ -412,21 +414,23 @@ public class ConfigureDRM {
         }
     }
 
-    public boolean LdapConnectionPanel() {
+    public boolean LdapConnectionPanel() throws UnsupportedEncodingException {
         HTTPResponse hr = null;
         ByteArrayInputStream bais = null;
         ParseXML px = new ParseXML();
 
         String query_string = "p=7" + "&op=next" + "&xml=true" +
-                              "&host=" + URLEncoder.encode(ldap_host) +
-                              "&port=" + URLEncoder.encode(ldap_port) +
-                              "&binddn=" + URLEncoder.encode(bind_dn) +
-                              "&__bindpwd=" + URLEncoder.encode(bind_password) +
-                              "&basedn=" + URLEncoder.encode(base_dn) +
-                              "&database=" + URLEncoder.encode(db_name) +
-                              "&display=" + URLEncoder.encode("$displayStr") +
+                              "&host=" + URLEncoder.encode(ldap_host, "UTF-8") +
+                              "&port=" + URLEncoder.encode(ldap_port, "UTF-8") +
+                              "&binddn=" + URLEncoder.encode(bind_dn, "UTF-8") +
+                              "&__bindpwd=" + URLEncoder.encode(bind_password, "UTF-8") +
+                              "&basedn=" + URLEncoder.encode(base_dn, "UTF-8") +
+                              "&database=" + URLEncoder.encode(db_name, "UTF-8") +
+                              "&display=" + URLEncoder.encode("$displayStr", "UTF-8") +
                               (secure_conn.equals("true") ? "&secureConn=on" : "") +
-                              (clone_start_tls.equals("true") ? "&cloneStartTLS=on" : "") +
+                              "&masterReplicationPort=" + URLEncoder.encode(clone_master_port, "UTF-8") +
+                              "&cloneReplicationPort=" + URLEncoder.encode(clone_replica_port, "UTF-8") +
+                              "&replicationSecurity=" + URLEncoder.encode(clone_replication_security, "UTF-8") +
                               (remove_data.equals("true") ? "&removeData=true" : "");
 
         hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string);
@@ -1017,7 +1021,6 @@ public class ConfigureDRM {
         StringHolder x_base_dn = new StringHolder();
         StringHolder x_db_name = new StringHolder();
         StringHolder x_secure_conn = new StringHolder();
-        StringHolder x_clone_start_tls = new StringHolder();
         StringHolder x_remove_data = new StringHolder();
 
         // key properties (defaults)
@@ -1078,6 +1081,9 @@ public class ConfigureDRM {
         StringHolder x_clone_uri = new StringHolder();
         StringHolder x_clone_p12_file = new StringHolder();
         StringHolder x_clone_p12_passwd = new StringHolder();
+        StringHolder x_clone_master_port = new StringHolder();
+        StringHolder x_clone_replica_port = new StringHolder();
+        StringHolder x_clone_replication_security = new StringHolder();
 
         // parse the args
         ArgParser parser = new ArgParser("ConfigureDRM");
@@ -1139,9 +1145,6 @@ public class ConfigureDRM {
         parser.addOption("-secure_conn %s #use ldaps port (optional, default is false)", x_secure_conn);
         parser.addOption("-remove_data %s #remove existing data under base_dn (optional, default is false) ",
                 x_remove_data);
-        parser.addOption(
-                "-clone_start_tls %s #use startTLS for cloning replication agreement (optional, default is false)",
-                x_clone_start_tls);
 
         // key and algorithm options (default)
         parser.addOption("-key_type %s #Key type [RSA,ECC] (optional, default is RSA)", x_key_type);
@@ -1242,6 +1245,15 @@ public class ConfigureDRM {
         parser.addOption("-clone_p12_password %s #Password for pk12 file (optional, required if -clone=true)",
                 x_clone_p12_passwd);
 
+        // replication agreement options
+        parser.addOption("-clone_master_port %s #Master Port to be used in replication agreement (optional)",
+                x_clone_master_port);
+        parser.addOption("-clone_replica_port %s #Replica Port to be used in replication agreement (optional)",
+                x_clone_replica_port);
+        parser.addOption("-clone_replication_security %s #Type of security in replication agreement (optional)",
+                x_clone_replication_security);
+
+
         // and then match the arguments
         String[] unmatched = null;
         unmatched = parser.matchAllArgs(args, 0, ArgParser.EXIT_ON_UNMATCHED);
@@ -1286,7 +1298,6 @@ public class ConfigureDRM {
         db_name = x_db_name.value;
         secure_conn = set_default(x_secure_conn.value, "false");
         remove_data = set_default(x_remove_data.value, "false");
-        clone_start_tls = set_default(x_clone_start_tls.value, "false");
 
         key_type = set_default(x_key_type.value, DEFAULT_KEY_TYPE);
         transport_key_type = set_default(x_transport_key_type.value, key_type);
@@ -1345,6 +1356,9 @@ public class ConfigureDRM {
         clone_uri = x_clone_uri.value;
         clone_p12_file = x_clone_p12_file.value;
         clone_p12_passwd = x_clone_p12_passwd.value;
+        clone_master_port = set_default(x_clone_master_port.value, "");
+        clone_replica_port = set_default(x_clone_replica_port.value, "");
+        clone_replication_security = set_default(x_clone_replication_security.value, "None");
 
         boolean st = ca.ConfigureDRMInstance();
 
diff --git a/pki/dogtag/common-ui/shared/admin/console/config/databasepanel.vm b/pki/dogtag/common-ui/shared/admin/console/config/databasepanel.vm
index 36439b4e640ff3a01cfd1496f1e90b7298e1fe7c..95086808b82023a0b295a9f13d7a4f9fd0bfd983 100644
--- a/pki/dogtag/common-ui/shared/admin/console/config/databasepanel.vm
+++ b/pki/dogtag/common-ui/shared/admin/console/config/databasepanel.vm
@@ -43,7 +43,8 @@ function toggle_details()
 Each instance needs access to a Fedora Directory Server instance to store requests and records. Each PKI instance may create its own associated internal database, or may share an existing internal database. To share an existing internal database instance, a PKI instance would only need to establish a unique distinguished name (DN) using the field entitled <b>Base DN</b> and a unique database name using the field entitled <b>Database</b>. 
 #if ($clone == "clone")
 <p>
-If the replication between the masters and clones occurs on the non-SSL port, it is still possible to require the replication to be SSL encrypted by selecting <b> Use StartTLS with replication agreements</b> below.  In order for this operation to be successful, the database instances must be SSL enabled before continuing beyond this panel.
+<p>
+Replication agreements between the master and clone database instances may be customized.  If no master and replication ports are provided, then replication will occur on the same ports used by the Certificate Sever instances to communicate with the directory server.  If these ports are LDAPS ports, then the replication traffic will be SSL encrypted.  It is still possible to require the replication traffic to be SSL encrypted on the non-SSL port by selecting TLS for Replication Security.  In order for this operation to be successful though, the database instances must be SSL enabled before continuing beyond this panel.
 #end
 </div>
 <p>
@@ -64,8 +65,8 @@ If the replication between the masters and clones occurs on the non-SSL port, it
         <th>Port:</th>
                                 
         <td><input type="text" size="40" name="port" value="$portStr" />  
-<input type="CHECKBOX" NAME="secureConn">SSL
-</td>
+            <input type="CHECKBOX" NAME="secureConn">SSL
+        </td>
       </tr>       
       <tr>
         <th>Base DN:</th>
@@ -90,12 +91,40 @@ If the replication between the masters and clones occurs on the non-SSL port, it
         <td><input type="password" size="40" name="__bindpwd" value="$bindpwd" autocomplete="off" /></td>
       </tr>
     </table>
-        <input type="hidden" name="display" value=$displayStr />
- 
-#if ($clone == "clone") 
-      <input type="CHECKBOX" NAME="cloneStartTLS"/>Use StartTLS with replication agreements.<p>
-#end 
-<input type="CHECKBOX" NAME="removeData">Remove the existing data from the <b>Base DN</b> shown above.<p>
+    <input type="hidden" name="display" value=$displayStr />
+    <input type="CHECKBOX" NAME="removeData">Remove the existing data from the <b>Base DN</b> shown above.<p>
+
+#if ($clone == "clone")
+
+    #set ($check_none="")
+    #set ($check_tls="")
+    #set ($check_ssl="")
+    #if ($replicationSecurity == "TLS") #set ($check_tls="CHECKED")
+    #elseif ($replicationSecurity == "SSL") #set ($check_ssl="CHECKED")
+    #else #set ($check_none="CHECKED") #end
+
+    <table class="details" >
+      <tr><th>Replication Details</th></tr>
+      <tr>
+        <th>Master Replication Port:</th>
+        <td><input type="text" size="40" name="masterReplicationPort" value="$masterReplicationPort" /></td>
+      </tr>
+
+      <tr>
+        <th>Clone Replication Port:</th>
+        <td><input type="text" size="40" name="cloneReplicationPort" value="$cloneReplicationPort" /></td>
+      </tr>
+
+      <tr>
+        <th>Replication Security:</th>
+        <td>
+            <input type="radio" name="replicationSecurity" value="None" $check_none />None</input>
+            <input type="radio" name="replicationSecurity" value="TLS"  $check_tls  />TLS</input>
+            <input type="radio" name="replicationSecurity" value="SSL"  $check_ssl  />SSL</input>
+        </td>
+      </tr>
+      <p>
+#end
 
     <div align="right">
       <hr />
-- 
1.7.6.4

