From 4651639bf51cb2ed91d474d85761c0249d7050de Mon Sep 17 00:00:00 2001
From: Matthew Harmsen <mharmsen@redhat.com>
Date: Wed, 1 Aug 2012 21:36:28 -0700
Subject: [PATCH] PKI Deployment Scriptlets

* PKI TRAC Ticket #279 - Dogtag 10: Fix remaining 'cloning' issues in
  'pkispawn' . . .
* PKI TRAC Ticket #280 - Dogtag 10: Fix remaining issues in 'pkidestroy'
  related to deletion of more than one instance . . .
* PKI TRAC Ticket #281 - Dogtag 10: Fix 'pkidaemon'/'operations' issue to
  handle individual instance . . .
---
 .../cms/servlet/csadmin/ConfigurationUtils.java    |    2 +-
 .../cms/servlet/csadmin/RestoreKeyCertPanel.java   |    6 +-
 base/deploy/scripts/operations                     |   98 +++++++++++
 base/deploy/scripts/pkidaemon                      |   14 ++
 base/deploy/src/scriptlets/configuration.jy        |   21 +--
 base/deploy/src/scriptlets/configuration.py        |   36 ++--
 base/deploy/src/scriptlets/finalization.py         |    8 +-
 .../deploy/src/scriptlets/infrastructure_layout.py |    4 +-
 base/deploy/src/scriptlets/instance_layout.py      |   39 +++--
 base/deploy/src/scriptlets/pkihelper.py            |  176 ++++++++++++++++++--
 base/deploy/src/scriptlets/pkijython.py            |  172 ++++++++++---------
 base/deploy/src/scriptlets/pkimessages.py          |   14 +-
 base/deploy/src/scriptlets/pkiparser.py            |   49 ++++--
 base/deploy/src/scriptlets/security_databases.py   |    8 +-
 14 files changed, 484 insertions(+), 163 deletions(-)

diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index cc88084..50c7853 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -719,7 +719,7 @@ public class ConfigurationUtils {
         IConfigStore cs = CMS.getConfigStore();
         String instanceRoot = cs.getString("instanceRoot");
 
-        FileInputStream fis = new FileInputStream(instanceRoot + "/alias/" + p12File);
+        FileInputStream fis = new FileInputStream(p12File);
         while (fis.available() > 0)
             fis.read(b);
         fis.close();
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java b/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
index 7ace274..243e7e8 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java
@@ -17,6 +17,7 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cms.servlet.csadmin;
 
+import java.io.File;
 import java.io.IOException;
 
 import javax.servlet.ServletConfig;
@@ -191,7 +192,10 @@ public class RestoreKeyCertPanel extends WizardPanelBase {
 
             String tokenn = config.getString("preop.module.token");
             if (tokenn.equals("Internal Key Storage Token")) {
-                ConfigurationUtils.restoreCertsFromP12(path, pwd);
+                String instanceRoot = config.getString("instanceRoot");
+                String p12File = instanceRoot + File.separator + "alias" +
+                                 File.separator + path;
+                ConfigurationUtils.restoreCertsFromP12(p12File, pwd);
             }
 
             String subsystemtype = config.getString("preop.subsystem.select", "");
diff --git a/base/deploy/scripts/operations b/base/deploy/scripts/operations
index a2f88b3..23e5e21 100644
--- a/base/deploy/scripts/operations
+++ b/base/deploy/scripts/operations
@@ -40,6 +40,10 @@ case $command in
         # 1 generic or unspecified error (current practice)
         default_error=1
         ;;
+    start_all|stop_all|restart_all)
+        # 1 generic or unspecified error (current practice)
+        default_error=1
+        ;;
     reload)
         default_error=3
         ;;
@@ -148,6 +152,9 @@ usage()
     echo -n "{start"
     echo -n "|stop"
     echo -n "|restart"
+    echo -n "|start_all"
+    echo -n "|stop_all"
+    echo -n "|restart_all"
     echo -n "|condrestart"
     echo -n "|force-restart"
     echo -n "|try-restart"
@@ -164,6 +171,9 @@ usage_systemd()
     echo -n "{start"
     echo -n "|stop"
     echo -n "|restart"
+    echo -n "|start_all"
+    echo -n "|stop_all"
+    echo -n "|restart_all"
     echo -n "|condrestart"
     echo -n "|force-restart"
     echo -n "|try-restart"
@@ -921,6 +931,54 @@ start()
         return 5
     fi
 
+    # Source values associated with this particular PKI instance
+    [ -f ${PKI_REGISTRY_ENTRY} ] &&
+    . ${PKI_REGISTRY_ENTRY}
+
+    start_instance
+    rv=$?
+    if [ $rv = 6 ] ; then
+        # Since at least ONE configuration error exists, then there
+        # is at least ONE unconfigured instance from the PKI point
+        # of view.
+        #
+        # However, it must still be considered that the
+        # instance is "running" from the point of view of other
+        # OS programs such as 'chkconfig'.
+        #
+        # Therefore, ignore non-zero return codes resulting
+        # from configuration errors.
+        #
+
+        config_errors=`expr $config_errors + 1`
+        rv=0
+    elif [ $rv != 0 ] ; then
+        errors=`expr $errors + 1`
+        error_rv=$rv
+    fi
+
+    if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt ${errors} ] ; then
+        touch ${lockfile}
+        chmod 00600 ${lockfile}
+    fi
+
+    return $rv
+}
+
+start_all()
+{
+    error_rv=0
+    rv=0
+    config_errors=0
+    errors=0
+
+    if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+        echo
+        echo "ERROR:  No '${PKI_TYPE}' instances installed!"
+        # 5 program is not installed
+        return 5
+    fi
+
     if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ]; then
         echo "BEGIN STARTING '${PKI_TYPE}' INSTANCES:"
     fi
@@ -1011,6 +1069,37 @@ stop()
         return 5
     fi
 
+    # Source values associated with this particular PKI instance
+    [ -f ${PKI_REGISTRY_ENTRY} ] &&
+    . ${PKI_REGISTRY_ENTRY}
+
+    stop_instance
+    rv=$?
+    if [ $rv != 0 ] ; then
+        errors=`expr $errors + 1`
+        error_rv=$rv
+    fi
+
+    if [ ${errors} -eq 0 ] ; then
+        rm -f ${lockfile}
+    fi
+
+    return $rv
+}
+
+stop_all()
+{
+    error_rv=0
+    rv=0
+    errors=0
+
+    if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+        echo
+        echo "ERROR:  No '${PKI_TYPE}' instances installed!"
+        # 5 program is not installed
+        return 5
+    fi
+
     if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
         echo "BEGIN SHUTTING DOWN '${PKI_TYPE}' INSTANCE(S):"
     fi
@@ -1072,6 +1161,15 @@ restart()
     return $?
 }
 
+restart_all()
+{
+    stop_all
+    sleep 2
+    start_all
+
+    return $?
+}
+
 registry_status()
 {
     error_rv=0
diff --git a/base/deploy/scripts/pkidaemon b/base/deploy/scripts/pkidaemon
index 02b0237..74f69e9 100755
--- a/base/deploy/scripts/pkidaemon
+++ b/base/deploy/scripts/pkidaemon
@@ -56,6 +56,20 @@ case $command in
         stop
         exit $?
         ;;
+    start_all)
+        start_all
+        exit $?
+        ;;
+    restart_all)
+        restart_all
+        exit $?
+        ;;
+    stop_all)
+        echo "An exit status of '143' refers to the 'systemd' method of using"\
+             "'SIGTERM' to shutdown a Java process and can safely be ignored."
+        stop_all
+        exit $?
+        ;;
     condrestart|force-restart|try-restart)
         [ ! -f ${lockfile} ] || restart
         echo "The '${command}' action is TBD."
diff --git a/base/deploy/src/scriptlets/configuration.jy b/base/deploy/src/scriptlets/configuration.jy
index d06119a..290a2cc 100644
--- a/base/deploy/src/scriptlets/configuration.jy
+++ b/base/deploy/src/scriptlets/configuration.jy
@@ -97,42 +97,35 @@ def main(argv):
                   (log.PKI_JYTHON_INDENTATION_2,
                    master['pki_subsystem'],
                    log.PKI_JYTHON_NOT_YET_IMPLEMENTED)
-            return self.rv
+            return rv
         elif master['pki_subsystem'] == "TPS":
             print "%s '%s' %s" %\
                   (log.PKI_JYTHON_INDENTATION_2,
                    master['pki_subsystem'],
                    log.PKI_JYTHON_NOT_YET_IMPLEMENTED)
-            return self.rv
+            return rv
     elif master['pki_instance_type'] == "Tomcat":
         if master['pki_subsystem'] == "CA":
-            if config.str2bool(master['pki_clone']):
-                print "%s '%s %s' %s" %\
-                      (log.PKI_JYTHON_INDENTATION_2,
-                       log.PKI_JYTHON_CLONED_PKI_SUBSYSTEM,
-                       master['pki_subsystem'],
-                       log.PKI_JYTHON_NOT_YET_IMPLEMENTED)
-                return self.rv
-            elif config.str2bool(master['pki_external']):
+            if config.str2bool(master['pki_external']):
                 print "%s '%s %s' %s" %\
                       (log.PKI_JYTHON_INDENTATION_2,
                        log.PKI_JYTHON_EXTERNAL_CA,
                        master['pki_subsystem'],
                        log.PKI_JYTHON_NOT_YET_IMPLEMENTED)
-                return self.rv
+                return rv
             elif config.str2bool(master['pki_subordinate']):
                 print "%s '%s %s' %s" %\
                       (log.PKI_JYTHON_INDENTATION_2,
                        log.PKI_JYTHON_SUBORDINATE_CA,
                        master['pki_subsystem'],
                        log.PKI_JYTHON_NOT_YET_IMPLEMENTED)
-                return self.rv
+                return rv
             else:
-                # CA
+                # PKI or Cloned CA
                 data = jyutil.rest_client.construct_pki_configuration_data(
                            master, sensitive, token)
         else:
-            # KRA, OCSP, or TKS
+            # PKI or Cloned KRA, OCSP, or TKS
             data = jyutil.rest_client.construct_pki_configuration_data(
                        master, sensitive, token)
 
diff --git a/base/deploy/src/scriptlets/configuration.py b/base/deploy/src/scriptlets/configuration.py
index 365bc39..f7a9a66 100644
--- a/base/deploy/src/scriptlets/configuration.py
+++ b/base/deploy/src/scriptlets/configuration.py
@@ -88,10 +88,11 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         # Start/Restart this Apache/Tomcat PKI Process
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
-                apache_instances = util.instance.apache_instances()
-                if apache_instances == 1:
+                apache_instance_subsystems =\
+                    util.instance.apache_instance_subsystems()
+                if apache_instance_subsystems == 1:
                     util.systemd.start()
-                elif apache_instances > 1:
+                elif apache_instance_subsystems > 1:
                     util.systemd.restart()
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
                 # Optionally prepare to enable a java debugger
@@ -99,18 +100,20 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 if config.str2bool(master['pki_enable_java_debugger']):
                     config.prepare_for_an_external_java_debugger(
                         master['pki_target_tomcat_conf_instance_id'])
-                tomcat_instances = util.instance.tomcat_instances()
-                if tomcat_instances == 1:
+                tomcat_instance_subsystems =\
+                    util.instance.tomcat_instance_subsystems()
+                if tomcat_instance_subsystems == 1:
                     util.systemd.start()
-                elif tomcat_instances > 1:
+                elif tomcat_instance_subsystems > 1:
                     util.systemd.restart()
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS:
-                apache_instances = util.instance.apache_instances()
-                if apache_instances == 0:
+                apache_instance_subsystems =\
+                    util.instance.apache_instance_subsystems()
+                if apache_instance_subsystems == 0:
                     util.systemd.start()
-                elif apache_instances > 0:
+                elif apache_instance_subsystems > 0:
                     util.systemd.restart()
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
                 # Optionally prepare to enable a java debugger
@@ -118,10 +121,11 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 if config.str2bool(master['pki_enable_java_debugger']):
                     config.prepare_for_an_external_java_debugger(
                         master['pki_target_tomcat_conf_instance_id'])
-                tomcat_instances = util.instance.tomcat_instances()
-                if tomcat_instances == 0:
+                tomcat_instance_subsystems =\
+                    util.instance.tomcat_instance_subsystems()
+                if tomcat_instance_subsystems == 0:
                     util.systemd.start()
-                elif tomcat_instances > 0:
+                elif tomcat_instance_subsystems > 0:
                     util.systemd.restart()
         # Pass control to the Java servlet via Jython 2.2 'configuration.jy'
         util.jython.invoke(master['pki_jython_configuration_scriptlet'])
@@ -145,24 +149,24 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                             extra=config.PKI_INDENTATION_LEVEL_1)
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 1:
+               util.instance.apache_instance_subsystems() == 1:
                 if util.directory.exists(master['pki_client_dir']):
                     util.directory.delete(master['pki_client_dir'])
                 util.symlink.delete(master['pki_systemd_service_link'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 1:
+                 util.instance.tomcat_instance_subsystems() == 1:
                 if util.directory.exists(master['pki_client_dir']):
                     util.directory.delete(master['pki_client_dir'])
                 util.symlink.delete(master['pki_systemd_service_link'])
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 0:
+               util.instance.apache_instance_subsystems() == 0:
                 if util.directory.exists(master['pki_client_dir']):
                     util.directory.delete(master['pki_client_dir'])
                 util.symlink.delete(master['pki_systemd_service_link'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 0:
+                 util.instance.tomcat_instance_subsystems() == 0:
                 if util.directory.exists(master['pki_client_dir']):
                     util.directory.delete(master['pki_client_dir'])
                 util.symlink.delete(master['pki_systemd_service_link'])
diff --git a/base/deploy/src/scriptlets/finalization.py b/base/deploy/src/scriptlets/finalization.py
index ab66cd7..05fd47c 100644
--- a/base/deploy/src/scriptlets/finalization.py
+++ b/base/deploy/src/scriptlets/finalization.py
@@ -129,18 +129,18 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         # Start this Apache/Tomcat PKI Process
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() >= 1:
+               util.instance.apache_instance_subsystems() >= 1:
                 util.systemd.start()
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() >= 1:
+                 util.instance.tomcat_instance_subsystems() >= 1:
                 util.systemd.start()
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() >= 0:
+               util.instance.apache_instance_subsystems() >= 0:
                 util.systemd.start()
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() >= 0:
+                 util.instance.tomcat_instance_subsystems() >= 0:
                 util.systemd.start()
         config.pki_log.info(log.PKIDESTROY_END_MESSAGE_2,
                             master['pki_subsystem'],
diff --git a/base/deploy/src/scriptlets/infrastructure_layout.py b/base/deploy/src/scriptlets/infrastructure_layout.py
index 4baada9..586cc88 100644
--- a/base/deploy/src/scriptlets/infrastructure_layout.py
+++ b/base/deploy/src/scriptlets/infrastructure_layout.py
@@ -98,7 +98,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         # remove top-level infrastructure base
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_SUBSYSTEMS and\
-               util.instance.pki_subsystem_instances() == 0:
+               util.instance.pki_instance_subsystems() == 0:
                 # remove top-level infrastructure base
                 util.directory.delete(master['pki_path'])
                 # do NOT remove top-level infrastructure logs
@@ -114,7 +114,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_SUBSYSTEMS and\
-               util.instance.pki_subsystem_instances() == 1:
+               util.instance.pki_instance_subsystems() == 1:
                 # remove top-level infrastructure base
                 util.directory.delete(master['pki_path'])
                 # do NOT remove top-level infrastructure logs
diff --git a/base/deploy/src/scriptlets/instance_layout.py b/base/deploy/src/scriptlets/instance_layout.py
index 013a960..d29b2d2 100644
--- a/base/deploy/src/scriptlets/instance_layout.py
+++ b/base/deploy/src/scriptlets/instance_layout.py
@@ -85,6 +85,8 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 master['pki_commons_codec_jar_link'])
             util.symlink.create(master['pki_httpclient_jar'],
                 master['pki_httpclient_jar_link'])
+            util.symlink.create(master['pki_httpcore_jar'],
+                master['pki_httpcore_jar_link'])
             util.symlink.create(master['pki_javassist_jar'],
                 master['pki_javassist_jar_link'])
             util.symlink.create(master['pki_resteasy_jaxrs_api_jar'],
@@ -188,6 +190,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
             util.symlink.modify(master['pki_apache_commons_logging_jar_link'])
             util.symlink.modify(master['pki_commons_codec_jar_link'])
             util.symlink.modify(master['pki_httpclient_jar_link'])
+            util.symlink.modify(master['pki_httpcore_jar_link'])
             util.symlink.modify(master['pki_javassist_jar_link'])
             util.symlink.modify(master['pki_resteasy_jaxrs_api_jar_link'])
             util.symlink.modify(master['pki_jettison_jar_link'])
@@ -227,7 +230,7 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                             extra=config.PKI_INDENTATION_LEVEL_1)
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 0:
+               util.instance.apache_instance_subsystems() == 0:
                 # remove Apache instance base
                 util.directory.delete(master['pki_instance_path'])
                 # remove Apache instance logs
@@ -236,9 +239,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 # remove Apache instance configuration
                 util.directory.delete(master['pki_instance_configuration_path'])
                 # remove Apache instance registry
-                util.directory.delete(master['pki_instance_type_registry_path'])
+                util.directory.delete(master['pki_instance_registry_path'])
+                # remove Apache PKI registry (if empty)
+                if util.instance.apache_instances() == 0:
+                    util.directory.delete(
+                        master['pki_instance_type_registry_path'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 0:
+                 util.instance.tomcat_instance_subsystems() == 0:
                 # remove Tomcat instance base
                 util.directory.delete(master['pki_instance_path'])
                 # remove Tomcat instance logs
@@ -249,14 +256,18 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 util.symlink.delete(
                     master['pki_tomcat_lib_log4j_properties_link'])
                 util.directory.delete(master['pki_instance_configuration_path'])
-                # remove Tomcat instance registry
-                util.directory.delete(master['pki_instance_type_registry_path'])
                 # remove PKI 'tomcat.conf' instance file
                 util.file.delete(master['pki_target_tomcat_conf_instance_id'])
+                # remove Tomcat instance registry
+                util.directory.delete(master['pki_instance_registry_path'])
+                # remove Tomcat PKI registry (if empty)
+                if util.instance.tomcat_instances() == 0:
+                    util.directory.delete(
+                        master['pki_instance_type_registry_path'])
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 1:
+               util.instance.apache_instance_subsystems() == 1:
                 # remove Apache instance base
                 util.directory.delete(master['pki_instance_path'])
                 # remove Apache instance logs
@@ -265,9 +276,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 # remove Apache instance configuration
                 util.directory.delete(master['pki_instance_configuration_path'])
                 # remove Apache instance registry
-                util.directory.delete(master['pki_instance_type_registry_path'])
+                util.directory.delete(master['pki_instance_registry_path'])
+                # remove Apache PKI registry (if empty)
+                if util.instance.apache_instances() == 1:
+                    util.directory.delete(
+                        master['pki_instance_type_registry_path'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 1:
+                 util.instance.tomcat_instance_subsystems() == 1:
                 # remove Tomcat instance base
                 util.directory.delete(master['pki_instance_path'])
                 # remove Tomcat instance logs
@@ -278,8 +293,12 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                 util.symlink.delete(
                     master['pki_tomcat_lib_log4j_properties_link'])
                 util.directory.delete(master['pki_instance_configuration_path'])
-                # remove Tomcat instance registry
-                util.directory.delete(master['pki_instance_type_registry_path'])
                 # remove PKI 'tomcat.conf' instance file
                 util.file.delete(master['pki_target_tomcat_conf_instance_id'])
+                # remove Tomcat instance registry
+                util.directory.delete(master['pki_instance_registry_path'])
+                # remove Tomcat PKI registry (if empty)
+                if util.instance.tomcat_instances() == 1:
+                    util.directory.delete(
+                        master['pki_instance_type_registry_path'])
         return self.rv
diff --git a/base/deploy/src/scriptlets/pkihelper.py b/base/deploy/src/scriptlets/pkihelper.py
index 61ac202..c0dc14d 100644
--- a/base/deploy/src/scriptlets/pkihelper.py
+++ b/base/deploy/src/scriptlets/pkihelper.py
@@ -540,12 +540,92 @@ class configuration_file:
         #          ALL name/value pairs for the requested configuration
         #          scenario.  This should include checking for the
         #          "existence" of ALL required "name" parameters, as well as
-        #          the "existence", "type", and "correctness" of ALL required
-        #          "value" parameters.
+        #          the "existence", "type" (e. g. -  string, boolean, number,
+        #          etc.), and "correctness" (e. g. - file, directory, boolean
+        #          'True' or 'False', etc.) of ALL required "value" parameters.
         #
         if master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS:
-            if config.str2bool(config.pki_master_dict['pki_clone']):
+            if config.str2bool(master['pki_clone']):
                 # Verify existence of clone parameters
+                if not master.has_key('pki_ds_base_dn') or\
+                   not len(master['pki_ds_base_dn']):
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_ds_base_dn",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                if not master.has_key('pki_ds_ldap_port') or\
+                   not len(master['pki_ds_ldap_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_ds_ldap_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                if not master.has_key('pki_ds_ldaps_port') or\
+                   not len(master['pki_ds_ldaps_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_ds_ldaps_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                # NOTE:  Although this will be checked prior to getting to
+                #        this method, this clone's 'pki_instance_name' MUST
+                #        be different from the master's 'pki_instance_name'
+                #        IF AND ONLY IF the master and clone are located on
+                #        the same host!
+                if not master.has_key('pki_ajp_port') or\
+                   not len(master['pki_ajp_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_ajp_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                if not master.has_key('pki_http_port') or\
+                   not len(master['pki_http_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_http_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                if not master.has_key('pki_https_port') or\
+                   not len(master['pki_https_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_https_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
+                if not master.has_key('pki_tomcat_server_port') or\
+                   not len(master['pki_tomcat_server_port']):
+                    # FUTURE:  Check for unused port value
+                    #          (e. g. - must be different from master if the
+                    #                   master is located on the same host)
+                    config.pki_log.error(
+                        log.PKIHELPER_UNDEFINED_CONFIGURATION_FILE_ENTRY_2,
+                        "pki_tomcat_server_port",
+                        master['pki_deployment_cfg'],
+                        extra=config.PKI_INDENTATION_LEVEL_2)
+                    sys.exit(1)
                 if not master.has_key('pki_clone_pkcs12_path') or\
                    not len(master['pki_clone_pkcs12_path']):
                     config.pki_log.error(
@@ -577,7 +657,7 @@ class configuration_file:
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     sys.exit(1)
             elif master['pki_subsystem'] == "CA" and\
-                 config.str2bool(config.pki_master_dict['pki_external']):
+                 config.str2bool(master['pki_external']):
                 if not master.has_key('pki_external_step_two') or\
                    not len(master['pki_external_step_two']):
                     config.pki_log.error(
@@ -586,7 +666,7 @@ class configuration_file:
                         master['pki_deployment_cfg'],
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     sys.exit(1)
-                if not config.str2bool(config.pki_master_dict['pki_step_two']):
+                if not config.str2bool(master['pki_step_two']):
                     if not master.has_key('pki_external_csr_path') or\
                        not len(master['pki_external_csr_path']):
                         config.pki_log.error(
@@ -735,7 +815,7 @@ class configuration_file:
 
 # PKI Deployment Instance Class
 class instance:
-    def apache_instances(self):
+    def apache_instance_subsystems(self):
         rv = 0
         try:
             # count number of PKI subsystems present
@@ -746,11 +826,11 @@ class instance:
                     rv = rv + 1
             # always display correct information (even during dry_run)
             if config.pki_dry_run_flag and rv > 0:
-                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'], rv - 1,
                                      extra=config.PKI_INDENTATION_LEVEL_2)
             else:
-                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'],
                                      rv, extra=config.PKI_INDENTATION_LEVEL_2)
         except OSError as exc:
@@ -759,7 +839,41 @@ class instance:
             sys.exit(1)
         return rv
 
-    def pki_subsystem_instances(self):
+    def apache_instances(self):
+        rv = 0
+        try:
+            # Since ALL directories under the top-level PKI 'apache' registry
+            # directory SHOULD represent PKI Apache instances, and there
+            # shouldn't be any stray files or symbolic links at this level,
+            # simply count the number of PKI 'apache' instances (directories)
+            # present within the PKI 'apache' registry directory
+            for instance in\
+                os.listdir(master['pki_instance_type_registry_path']):
+                if os.path.isdir(
+                       os.path.join(master['pki_instance_type_registry_path'],
+                       instance)) and not\
+                   os.path.islink(
+                       os.path.join(master['pki_instance_type_registry_path'],
+                       instance)):
+                    rv = rv + 1
+            # always display correct information (even during dry_run)
+            if config.pki_dry_run_flag and rv > 0:
+                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2,
+                                     master['pki_instance_type_registry_path'],
+                                     rv - 1,
+                                     extra=config.PKI_INDENTATION_LEVEL_2)
+            else:
+                config.pki_log.debug(log.PKIHELPER_APACHE_INSTANCES_2,
+                                     master['pki_instance_type_registry_path'],
+                                     rv,
+                                     extra=config.PKI_INDENTATION_LEVEL_2)
+        except OSError as exc:
+            config.pki_log.error(log.PKI_OSERROR_1, exc,
+                                 extra=config.PKI_INDENTATION_LEVEL_2)
+            sys.exit(1)
+        return rv
+
+    def pki_instance_subsystems(self):
         rv = 0
         try:
             # Since ALL directories within the top-level PKI infrastructure
@@ -780,11 +894,11 @@ class instance:
                                 rv = rv + 1
             # always display correct information (even during dry_run)
             if config.pki_dry_run_flag and rv > 0:
-                config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_PKI_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'], rv - 1,
                                      extra=config.PKI_INDENTATION_LEVEL_2)
             else:
-                config.pki_log.debug(log.PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_PKI_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'], rv,
                                      extra=config.PKI_INDENTATION_LEVEL_2)
         except OSError as exc:
@@ -793,7 +907,7 @@ class instance:
             sys.exit(1)
         return rv
 
-    def tomcat_instances(self):
+    def tomcat_instance_subsystems(self):
         rv = 0
         try:
             # count number of PKI subsystems present
@@ -804,11 +918,11 @@ class instance:
                     rv = rv + 1
             # always display correct information (even during dry_run)
             if config.pki_dry_run_flag and rv > 0:
-                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'], rv - 1,
                                      extra=config.PKI_INDENTATION_LEVEL_2)
             else:
-                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2,
+                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCE_SUBSYSTEMS_2,
                                      master['pki_instance_path'],
                                      rv, extra=config.PKI_INDENTATION_LEVEL_2)
         except OSError as exc:
@@ -817,6 +931,40 @@ class instance:
             sys.exit(1)
         return rv
 
+    def tomcat_instances(self):
+        rv = 0
+        try:
+            # Since ALL directories under the top-level PKI 'tomcat' registry
+            # directory SHOULD represent PKI Tomcat instances, and there
+            # shouldn't be any stray files or symbolic links at this level,
+            # simply count the number of PKI 'tomcat' instances (directories)
+            # present within the PKI 'tomcat' registry directory
+            for instance in\
+                os.listdir(master['pki_instance_type_registry_path']):
+                if os.path.isdir(
+                       os.path.join(master['pki_instance_type_registry_path'],
+                       instance)) and not\
+                   os.path.islink(
+                       os.path.join(master['pki_instance_type_registry_path'],
+                       instance)):
+                    rv = rv + 1
+            # always display correct information (even during dry_run)
+            if config.pki_dry_run_flag and rv > 0:
+                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2,
+                                     master['pki_instance_type_registry_path'],
+                                     rv - 1,
+                                     extra=config.PKI_INDENTATION_LEVEL_2)
+            else:
+                config.pki_log.debug(log.PKIHELPER_TOMCAT_INSTANCES_2,
+                                     master['pki_instance_type_registry_path'],
+                                     rv,
+                                     extra=config.PKI_INDENTATION_LEVEL_2)
+        except OSError as exc:
+            config.pki_log.error(log.PKI_OSERROR_1, exc,
+                                 extra=config.PKI_INDENTATION_LEVEL_2)
+            sys.exit(1)
+        return rv
+
     def verify_subsystem_exists(self):
         try:
             if not os.path.exists(master['pki_subsystem_path']):
diff --git a/base/deploy/src/scriptlets/pkijython.py b/base/deploy/src/scriptlets/pkijython.py
index 0c482bb..e08b490 100644
--- a/base/deploy/src/scriptlets/pkijython.py
+++ b/base/deploy/src/scriptlets/pkijython.py
@@ -287,6 +287,10 @@ class rest_client:
                         # Cloned CA
                         data.setHierarchy("root")
                         data.setIsClone("true")
+                        data.setCloneUri(master['pki_clone_uri'])
+                        data.setP12File(master['pki_clone_pkcs12_path'])
+                        data.setP12Password(
+                            sensitive['pki_clone_pkcs12_password'])
                     elif config.str2bool(master['pki_external']):
                         # External CA
                         data.setHierarchy("join")
@@ -303,6 +307,10 @@ class rest_client:
                     if config.str2bool(master['pki_clone']):
                         # Cloned KRA
                         data.setIsClone("true")
+                        data.setCloneUri(master['pki_clone_uri'])
+                        data.setP12File(master['pki_clone_pkcs12_path'])
+                        data.setP12Password(
+                            sensitive['pki_clone_pkcs12_password'])
                     else:
                         # PKI KRA
                         data.setIsClone("false")
@@ -310,6 +318,10 @@ class rest_client:
                     if config.str2bool(master['pki_clone']):
                         # Cloned OCSP
                         data.setIsClone("true")
+                        data.setCloneUri(master['pki_clone_uri'])
+                        data.setP12File(master['pki_clone_pkcs12_path'])
+                        data.setP12Password(
+                            sensitive['pki_clone_pkcs12_password'])
                     else:
                         # PKI OCSP
                         data.setIsClone("false")
@@ -317,6 +329,10 @@ class rest_client:
                     if config.str2bool(master['pki_clone']):
                         # Cloned TKS
                         data.setIsClone("true")
+                        data.setCloneUri(master['pki_clone_uri'])
+                        data.setP12File(master['pki_clone_pkcs12_path'])
+                        data.setP12Password(
+                            sensitive['pki_clone_pkcs12_password'])
                     else:
                         # PKI TKS
                         data.setIsClone("false")
@@ -562,9 +578,6 @@ class rest_client:
                 response = self.client.configure(data)
                 javasystem.out.println(log.PKI_JYTHON_RESPONSE_STATUS +\
                                        " " + response.getStatus())
-                admin_cert = response.getAdminCert().getCert()
-                javasystem.out.println(log.PKI_JYTHON_RESPONSE_ADMIN_CERT +\
-                                       " " + admin_cert)
                 certs = response.getSystemCerts()
                 iterator = certs.iterator()
                 while iterator.hasNext():
@@ -575,78 +588,87 @@ class rest_client:
                                            cdata.getCert())
                     javasystem.out.println(log.PKI_JYTHON_CDATA_REQUEST + " " +\
                                            cdata.getRequest())
-                # Store the Administration Certificate in a file
-                admin_cert_file = os.path.join(master['pki_client_dir'],
-                                               master['pki_client_admin_cert'])
-                javasystem.out.println(log.PKI_JYTHON_ADMIN_CERT_SAVE +\
-                                       " " + "'" + admin_cert_file + "'")
-                FILE = open(admin_cert_file, "w")
-                FILE.write(admin_cert)
-                FILE.close()
-                # Since Jython runs under Java, it does NOT support the
-                # following operating system specific command:
-                #
-                #     os.chmod(admin_cert_file,
-                #              config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS)
-                #
-                # Emulate it with a system call.
-                command = "chmod" + " " + "660" + " " + admin_cert_file
-                javasystem.out.println(
-                    log.PKI_JYTHON_CHMOD +\
-                    " " + "'" + command + "'")
-                os.system(command)
-                # Import the Administration Certificate
-                # into the client NSS security database
-                command = "certutil" + " " +\
-                          "-A" + " " +\
-                          "-n" + " " + "\"" +\
-                          re.sub("&#39;", "'", master['pki_admin_nickname']) +\
-                          "\"" + " " +\
-                          "-t" + " " +\
-                          "\"" + "u,u,u" + "\"" + " " +\
-                          "-f" + " " +\
-                          master['pki_client_password_conf'] + " " +\
-                          "-d" + " " +\
-                          master['pki_client_database_dir'] + " " +\
-                          "-a" + " " +\
-                          "-i" + " " +\
-                          admin_cert_file
-                javasystem.out.println(
-                    log.PKI_JYTHON_ADMIN_CERT_IMPORT +\
-                    " " + "'" + command + "'")
-                os.system(command)
-                # Export the Administration Certificate from the
-                # client NSS security database into a PKCS #12 file
-                command = "pk12util" + " " +\
-                          "-o" + " " +\
-                          master['pki_client_admin_cert_p12'] + " " +\
-                          "-n" + " " + "\"" +\
-                          re.sub("&#39;", "'", master['pki_admin_nickname']) +\
-                          "\"" + " " +\
-                          "-d" + " " +\
-                          master['pki_client_database_dir'] + " " +\
-                          "-k" + " " +\
-                          master['pki_client_password_conf'] + " " +\
-                          "-w" + " " +\
-                          master['pki_client_pkcs12_password_conf']
-                javasystem.out.println(
-                    log.PKI_JYTHON_ADMIN_CERT_EXPORT +\
-                    " " + "'" + command + "'")
-                os.system(command)
-                # Since Jython runs under Java, it does NOT support the
-                # following operating system specific command:
-                #
-                #     os.chmod(master['pki_client_admin_cert_p12'],
-                #         config.\
-                #         PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
-                #
-                # Emulate it with a system call.
-                command = "chmod" + " " + "664" + " " +\
-                          master['pki_client_admin_cert_p12']
-                javasystem.out.println(
-                    log.PKI_JYTHON_CHMOD +\
-                    " " + "'" + command + "'")
-                os.system(command)
+                # Cloned PKI subsystems do not return an Admin Certificate
+                if not config.str2bool(master['pki_clone']):
+                    admin_cert = response.getAdminCert().getCert()
+                    javasystem.out.println(log.PKI_JYTHON_RESPONSE_ADMIN_CERT +\
+                                           " " + admin_cert)
+                    # Store the Administration Certificate in a file
+                    admin_cert_file = os.path.join(
+                        master['pki_client_dir'],
+                        master['pki_client_admin_cert'])
+                    javasystem.out.println(log.PKI_JYTHON_ADMIN_CERT_SAVE +\
+                                           " " + "'" + admin_cert_file + "'")
+                    FILE = open(admin_cert_file, "w")
+                    FILE.write(admin_cert)
+                    FILE.close()
+                    # Since Jython runs under Java, it does NOT support the
+                    # following operating system specific command:
+                    #
+                    #     os.chmod(
+                    #         admin_cert_file,
+                    #         config.PKI_DEPLOYMENT_DEFAULT_FILE_PERMISSIONS)
+                    #
+                    # Emulate it with a system call.
+                    command = "chmod" + " " + "660" + " " + admin_cert_file
+                    javasystem.out.println(
+                        log.PKI_JYTHON_CHMOD +\
+                        " " + "'" + command + "'")
+                    os.system(command)
+                    # Import the Administration Certificate
+                    # into the client NSS security database
+                    command = "certutil" + " " +\
+                              "-A" + " " +\
+                              "-n" + " " + "\"" +\
+                              re.sub("&#39;",
+                                     "'", master['pki_admin_nickname']) +\
+                              "\"" + " " +\
+                              "-t" + " " +\
+                              "\"" + "u,u,u" + "\"" + " " +\
+                              "-f" + " " +\
+                              master['pki_client_password_conf'] + " " +\
+                              "-d" + " " +\
+                              master['pki_client_database_dir'] + " " +\
+                              "-a" + " " +\
+                              "-i" + " " +\
+                              admin_cert_file
+                    javasystem.out.println(
+                        log.PKI_JYTHON_ADMIN_CERT_IMPORT +\
+                        " " + "'" + command + "'")
+                    os.system(command)
+                    # Export the Administration Certificate from the
+                    # client NSS security database into a PKCS #12 file
+                    command = "pk12util" + " " +\
+                              "-o" + " " +\
+                              master['pki_client_admin_cert_p12'] + " " +\
+                              "-n" + " " + "\"" +\
+                              re.sub("&#39;",
+                                     "'", master['pki_admin_nickname']) +\
+                              "\"" + " " +\
+                              "-d" + " " +\
+                              master['pki_client_database_dir'] + " " +\
+                              "-k" + " " +\
+                              master['pki_client_password_conf'] + " " +\
+                              "-w" + " " +\
+                              master['pki_client_pkcs12_password_conf']
+                    javasystem.out.println(
+                        log.PKI_JYTHON_ADMIN_CERT_EXPORT +\
+                        " " + "'" + command + "'")
+                    os.system(command)
+                    # Since Jython runs under Java, it does NOT support the
+                    # following operating system specific command:
+                    #
+                    # os.chmod(master['pki_client_admin_cert_p12'],
+                    #     config.\
+                    #     PKI_DEPLOYMENT_DEFAULT_SECURITY_DATABASE_PERMISSIONS)
+                    #
+                    # Emulate it with a system call.
+                    command = "chmod" + " " + "664" + " " +\
+                              master['pki_client_admin_cert_p12']
+                    javasystem.out.println(
+                        log.PKI_JYTHON_CHMOD +\
+                        " " + "'" + command + "'")
+                    os.system(command)
             except Exception, e:
                 javasystem.out.println(
                     log.PKI_JYTHON_JAVA_CONFIGURATION_EXCEPTION + " " + str(e))
diff --git a/base/deploy/src/scriptlets/pkimessages.py b/base/deploy/src/scriptlets/pkimessages.py
index ccd7570..2b8a225 100644
--- a/base/deploy/src/scriptlets/pkimessages.py
+++ b/base/deploy/src/scriptlets/pkimessages.py
@@ -139,8 +139,10 @@ PKI_VERBOSITY
 
 
 # PKI Deployment "Helper" Messages
-PKIHELPER_APACHE_INSTANCES_2 = "instance '%s' contains '%d' "\
-                               "Apache PKI subsystems"
+PKIHELPER_APACHE_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
+                                         "Apache PKI subsystems"
+PKIHELPER_APACHE_INSTANCES_2 = "PKI Apache registry '%s' contains '%d' "\
+                               "Apache PKI instances"
 PKIHELPER_APPLY_SLOT_SUBSTITUTION_1 = "applying in-place "\
                                       "slot substitutions on '%s'"
 PKIHELPER_CERTUTIL_MISSING_ISSUER_NAME = "certutil:  Missing "\
@@ -214,7 +216,7 @@ PKIHELPER_NAMESPACE_RESERVED_NAME_2 = "PKI instance '%s' is already a "\
 PKIHELPER_NOISE_FILE_2 = "generating noise file called '%s' and "\
                          "filling it with '%d' random bytes"
 PKIHELPER_PASSWORD_CONF_1 = "generating '%s'"
-PKIHELPER_PKI_SUBSYSTEM_INSTANCES_2 = "instance '%s' contains '%d' "\
+PKIHELPER_PKI_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
                                       "PKI subsystems"
 PKIHELPER_REMOVE_FILTER_SECTION_1 = "removing filter section from '%s'"
 PKIHELPER_RM_F_1 = "rm -f %s"
@@ -223,8 +225,10 @@ PKIHELPER_RMDIR_1 = "rmdir %s"
 PKIHELPER_SET_MODE_1 = "setting ownerships, permissions, and acls on '%s'"
 PKIHELPER_SLOT_SUBSTITUTION_2 = "slot substitution: '%s' ==> '%s'"
 PKIHELPER_SYSTEMD_COMMAND_1 = "executing '%s'"
-PKIHELPER_TOMCAT_INSTANCES_2 = "instance '%s' contains '%d' "\
-                               "Tomcat PKI subsystems"
+PKIHELPER_TOMCAT_INSTANCE_SUBSYSTEMS_2 = "instance '%s' contains '%d' "\
+                                         "Tomcat PKI subsystems"
+PKIHELPER_TOMCAT_INSTANCES_2 = "PKI Tomcat registry '%s' contains '%d' "\
+                               "Tomcat PKI instances"
 PKIHELPER_TOUCH_1 = "touch %s"
 PKIHELPER_UID_2 = "UID of '%s' is %s"
 PKIHELPER_UNDEFINED_CLIENT_DATABASE_PASSWORD_2 =\
diff --git a/base/deploy/src/scriptlets/pkiparser.py b/base/deploy/src/scriptlets/pkiparser.py
index e39b197..5674cf8 100644
--- a/base/deploy/src/scriptlets/pkiparser.py
+++ b/base/deploy/src/scriptlets/pkiparser.py
@@ -633,6 +633,10 @@ def compose_pki_master_dictionary():
                 os.path.join(
                     config.PKI_DEPLOYMENT_HTTPCOMPONENTS_JAR_SOURCE_ROOT,
                     "httpclient.jar")
+            config.pki_master_dict['pki_httpcore_jar'] =\
+                os.path.join(
+                    config.PKI_DEPLOYMENT_HTTPCOMPONENTS_JAR_SOURCE_ROOT,
+                    "httpcore.jar")
             config.pki_master_dict['pki_javassist_jar'] =\
                 os.path.join(config.PKI_DEPLOYMENT_JAR_SOURCE_ROOT,
                              "javassist.jar")
@@ -722,6 +726,10 @@ def compose_pki_master_dictionary():
                 os.path.join(
                     config.pki_master_dict['pki_tomcat_common_lib_path'],
                     "httpclient.jar")
+            config.pki_master_dict['pki_httpcore_jar_link'] =\
+                os.path.join(
+                    config.pki_master_dict['pki_tomcat_common_lib_path'],
+                    "httpcore.jar")
             config.pki_master_dict['pki_javassist_jar_link'] =\
                 os.path.join(
                     config.pki_master_dict['pki_tomcat_common_lib_path'],
@@ -1493,7 +1501,14 @@ def compose_pki_master_dictionary():
                     config.pki_master_dict['pki_security_domain_uri'] =\
                         "https" + "://" +\
                         config.pki_master_dict['pki_security_domain_hostname']\
-                        + ":" + config.pki_security_domain_https_port
+                        + ":" +\
+                       config.pki_master_dict['pki_security_domain_https_port']
+                    if not len(config.pki_master_dict\
+                               ['pki_security_domain_name']):
+                        # Guess that security domain is on the local host
+                        config.pki_master_dict['pki_security_domain_name']\
+                            = config.pki_master_dict['pki_dns_domainname']\
+                            + " " + "Security Domain"
                     if config.str2bool(config.pki_master_dict['pki_clone']):
                         # Cloned CA
                         if not\
@@ -1510,12 +1525,6 @@ def compose_pki_master_dictionary():
                                 "Subordinate CA" + " " +\
                                 config.pki_master_dict['pki_hostname'] + " " +\
                                 config.pki_master_dict['pki_https_port']
-                        if not len(config.pki_master_dict\
-                                   ['pki_security_domain_name']):
-                            # Guess that security domain is on the local host
-                            config.pki_master_dict['pki_security_domain_name']\
-                                = config.pki_master_dict['pki_dns_domainname']\
-                                + " " + "Security Domain"
             else:
                 # PKI or Cloned KRA, OCSP, or TKS
                 config.pki_master_dict['pki_security_domain_type'] = "existing"
@@ -1529,13 +1538,11 @@ def compose_pki_master_dictionary():
                     config.pki_master_dict['pki_security_domain_hostname'] +\
                     ":" +\
                     config.pki_master_dict['pki_security_domain_https_port']
-                if not config.str2bool(config.pki_master_dict['pki_clone']):
-                    if not len(config.pki_master_dict\
-                               ['pki_security_domain_name']):
-                        # Guess that security domain is on the local host
-                        config.pki_master_dict['pki_security_domain_name'] =\
-                            config.pki_master_dict['pki_dns_domainname'] +\
-                            " " + "Security Domain"
+                if not len(config.pki_master_dict['pki_security_domain_name']):
+                    # Guess that security domain is on the local host
+                    config.pki_master_dict['pki_security_domain_name'] =\
+                        config.pki_master_dict['pki_dns_domainname'] +\
+                        " " + "Security Domain"
                 if config.pki_subsystem == "KRA":
                     if config.str2bool(config.pki_master_dict['pki_clone']):
                         # Cloned KRA
@@ -1614,9 +1621,17 @@ def compose_pki_master_dictionary():
         #         config.pki_master_dict['pki_ds_database']
         #         config.pki_master_dict['pki_ds_hostname']
         #
-        if not len(config.pki_master_dict['pki_ds_base_dn']):
-            config.pki_master_dict['pki_ds_base_dn'] =\
-                "o=" + config.pki_master_dict['pki_instance_id']
+        if not config.str2bool(config.pki_master_dict['pki_clone']):
+            if not len(config.pki_master_dict['pki_ds_base_dn']):
+                # if the instance is NOT a clone, create a default BASE DN
+                # of "o=${pki_instance_id}"; the reason that this default
+                # CANNOT be created if the instance is a clone is due to the
+                # fact that a master and clone MUST share the same BASE DN,
+                # and creating this default would prevent the ability to
+                # place a master and clone on the same machine (the method
+                # most often used for testing purposes)
+                config.pki_master_dict['pki_ds_base_dn'] =\
+                    "o=" + config.pki_master_dict['pki_instance_id']
         if not len(config.pki_master_dict['pki_ds_database']):
             config.pki_master_dict['pki_ds_database'] =\
                 config.pki_master_dict['pki_instance_id']
diff --git a/base/deploy/src/scriptlets/security_databases.py b/base/deploy/src/scriptlets/security_databases.py
index 73919ce..4b55cee 100644
--- a/base/deploy/src/scriptlets/security_databases.py
+++ b/base/deploy/src/scriptlets/security_databases.py
@@ -155,13 +155,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
                             extra=config.PKI_INDENTATION_LEVEL_1)
         if not config.pki_dry_run_flag:
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 0:
+               util.instance.apache_instance_subsystems() == 0:
                 util.file.delete(master['pki_cert_database'])
                 util.file.delete(master['pki_key_database'])
                 util.file.delete(master['pki_secmod_database'])
                 util.file.delete(master['pki_shared_password_conf'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 0:
+                 util.instance.tomcat_instance_subsystems() == 0:
                 util.file.delete(master['pki_cert_database'])
                 util.file.delete(master['pki_key_database'])
                 util.file.delete(master['pki_secmod_database'])
@@ -169,13 +169,13 @@ class PkiScriptlet(pkiscriptlet.AbstractBasePkiScriptlet):
         else:
             # ALWAYS display correct information (even during dry_run)
             if master['pki_subsystem'] in config.PKI_APACHE_SUBSYSTEMS and\
-               util.instance.apache_instances() == 1:
+               util.instance.apache_instance_subsystems() == 1:
                 util.file.delete(master['pki_cert_database'])
                 util.file.delete(master['pki_key_database'])
                 util.file.delete(master['pki_secmod_database'])
                 util.file.delete(master['pki_shared_password_conf'])
             elif master['pki_subsystem'] in config.PKI_TOMCAT_SUBSYSTEMS and\
-                 util.instance.tomcat_instances() == 1:
+                 util.instance.tomcat_instance_subsystems() == 1:
                 util.file.delete(master['pki_cert_database'])
                 util.file.delete(master['pki_key_database'])
                 util.file.delete(master['pki_secmod_database'])
-- 
1.7.10.4

