Blame SOURCES/pki-core-added-CLI-to-update-cert-data-and-request-in-CS-cfg.patch

efcdb2
commit 7ed1e32c574a2ee93a62297d16e07a7071e696d7
efcdb2
Author: Endi S. Dewata <edewata@redhat.com>
efcdb2
Date:   Wed Sep 2 04:50:24 2015 +0200
efcdb2
efcdb2
    Added CLI to update cert data and request in CS.cfg.
efcdb2
    
efcdb2
    A set of new pki-server commands have been added to simplify
efcdb2
    updating the cert data and cert request stored in the CS.cfg with
efcdb2
    the cert data and cert request stored in the NSS and LDAP database,
efcdb2
    respectively.
efcdb2
    
efcdb2
    https://fedorahosted.org/pki/ticket/1551
efcdb2
efcdb2
diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
efcdb2
index 9777d22..d004465 100644
efcdb2
--- a/base/server/python/pki/server/__init__.py
efcdb2
+++ b/base/server/python/pki/server/__init__.py
efcdb2
@@ -20,7 +20,11 @@
efcdb2
 #
efcdb2
 
efcdb2
 from lxml import etree
efcdb2
+import getpass
efcdb2
 import grp
efcdb2
+import io
efcdb2
+import ldap
efcdb2
+import operator
efcdb2
 import os
efcdb2
 import pwd
efcdb2
 import re
efcdb2
@@ -31,7 +35,7 @@ import pki
efcdb2
 INSTANCE_BASE_DIR = '/var/lib/pki'
efcdb2
 REGISTRY_DIR = '/etc/sysconfig/pki'
efcdb2
 SUBSYSTEM_TYPES = ['ca', 'kra', 'ocsp', 'tks', 'tps']
efcdb2
-
efcdb2
+SUBSYSTEM_CLASSES = {}
efcdb2
 
efcdb2
 class PKIServer(object):
efcdb2
 
efcdb2
@@ -65,6 +69,7 @@ class PKISubsystem(object):
efcdb2
             self.base_dir = instance.base_dir
efcdb2
 
efcdb2
         self.conf_dir = os.path.join(self.base_dir, 'conf')
efcdb2
+        self.cs_conf = os.path.join(self.conf_dir, 'CS.cfg')
efcdb2
 
efcdb2
         self.context_xml_template = os.path.join(
efcdb2
             pki.SHARE_DIR, self.name, 'conf', 'Catalina', 'localhost', self.name + '.xml')
efcdb2
@@ -72,9 +77,62 @@ class PKISubsystem(object):
efcdb2
         self.context_xml = os.path.join(
efcdb2
             instance.conf_dir, 'Catalina', 'localhost', self.name + '.xml')
efcdb2
 
efcdb2
+        self.config = {}
efcdb2
+        self.type = None
efcdb2
+        self.prefix = None
efcdb2
+
efcdb2
         # custom subsystem location
efcdb2
         self.doc_base = os.path.join(self.base_dir, 'webapps', self.name)
efcdb2
 
efcdb2
+    def load(self):
efcdb2
+        self.config.clear()
efcdb2
+
efcdb2
+        lines = open(self.cs_conf).read().splitlines()
efcdb2
+
efcdb2
+        for line in lines:
efcdb2
+            parts = line.split('=', 1)
efcdb2
+            name = parts[0]
efcdb2
+            value = parts[1]
efcdb2
+            self.config[name] = value
efcdb2
+
efcdb2
+        self.type = self.config['cs.type']
efcdb2
+        self.prefix = self.type.lower()
efcdb2
+
efcdb2
+    def find_subsystem_certs(self):
efcdb2
+        certs = []
efcdb2
+
efcdb2
+        cert_ids = self.config['%s.cert.list' % self.name].split(',')
efcdb2
+        for cert_id in cert_ids:
efcdb2
+            cert = self.create_subsystem_cert_object(cert_id)
efcdb2
+            certs.append(cert)
efcdb2
+
efcdb2
+        return certs
efcdb2
+
efcdb2
+    def get_subsystem_cert(self, cert_id):
efcdb2
+        return self.create_subsystem_cert_object(cert_id)
efcdb2
+
efcdb2
+    def create_subsystem_cert_object(self, cert_id):
efcdb2
+        cert = {}
efcdb2
+        cert['id'] = cert_id
efcdb2
+        cert['nickname'] = self.config.get('%s.%s.nickname' % (self.name, cert_id), None)
efcdb2
+        cert['token'] = self.config.get('%s.%s.tokenname' % (self.name, cert_id), None)
efcdb2
+        cert['data'] = self.config.get('%s.%s.cert' % (self.name, cert_id), None)
efcdb2
+        cert['request'] = self.config.get('%s.%s.certreq' % (self.name, cert_id), None)
efcdb2
+        return cert
efcdb2
+
efcdb2
+    def update_subsystem_cert(self, cert):
efcdb2
+        cert_id = cert['id']
efcdb2
+        self.config['%s.%s.nickname' % (self.name, cert_id)] = cert.get('nickname', None)
efcdb2
+        self.config['%s.%s.tokenname' % (self.name, cert_id)] = cert.get('token', None)
efcdb2
+        self.config['%s.%s.cert' % (self.name, cert_id)] = cert.get('data', None)
efcdb2
+        self.config['%s.%s.certreq' % (self.name, cert_id)] = cert.get('request', None)
efcdb2
+
efcdb2
+    def save(self):
efcdb2
+        sorted_config = sorted(self.config.items(), key=operator.itemgetter(0))
efcdb2
+        with io.open(self.cs_conf, 'wb') as f:
efcdb2
+            for (key, value) in sorted_config:
efcdb2
+                f.write('%s=%s\n' % (key, value))
efcdb2
+
efcdb2
     def is_valid(self):
efcdb2
         return os.path.exists(self.conf_dir)
efcdb2
 
efcdb2
@@ -102,6 +160,21 @@ class PKISubsystem(object):
efcdb2
     def disable(self):
efcdb2
         self.instance.undeploy(self.name)
efcdb2
 
efcdb2
+    def open_database(self, name='internaldb'):
efcdb2
+
efcdb2
+        hostname = self.config['%s.ldapconn.host' % name]
efcdb2
+        port = self.config['%s.ldapconn.port' % name]
efcdb2
+        bind_dn = self.config['%s.ldapauth.bindDN' % name]
efcdb2
+
efcdb2
+        # TODO: add support for other authentication
efcdb2
+        # mechanisms (e.g. client cert authentication, LDAPI)
efcdb2
+        bind_password = self.instance.get_password(name)
efcdb2
+
efcdb2
+        con = ldap.initialize('ldap://%s:%s' % (hostname, port))
efcdb2
+        con.simple_bind_s(bind_dn, bind_password)
efcdb2
+
efcdb2
+        return con
efcdb2
+
efcdb2
     def __repr__(self):
efcdb2
         return str(self.instance) + '/' + self.name
efcdb2
 
efcdb2
@@ -119,6 +192,9 @@ class PKIInstance(object):
efcdb2
             self.base_dir = os.path.join(pki.BASE_DIR, name)
efcdb2
 
efcdb2
         self.conf_dir = os.path.join(self.base_dir, 'conf')
efcdb2
+        self.password_conf = os.path.join(self.conf_dir, 'password.conf')
efcdb2
+
efcdb2
+        self.nssdb_dir = os.path.join(self.base_dir, 'alias')
efcdb2
         self.lib_dir = os.path.join(self.base_dir, 'lib')
efcdb2
 
efcdb2
         self.registry_dir = os.path.join(pki.server.REGISTRY_DIR, 'tomcat', self.name)
efcdb2
@@ -132,6 +208,8 @@ class PKIInstance(object):
efcdb2
         self.uid = None
efcdb2
         self.gid = None
efcdb2
 
efcdb2
+        self.passwords = {}
efcdb2
+
efcdb2
         self.subsystems = []
efcdb2
 
efcdb2
     def is_valid(self):
efcdb2
@@ -153,6 +231,7 @@ class PKIInstance(object):
efcdb2
         return rc == 0
efcdb2
 
efcdb2
     def load(self):
efcdb2
+        # load UID and GID
efcdb2
         with open(self.registry_file, 'r') as registry:
efcdb2
             lines = registry.readlines()
efcdb2
 
efcdb2
@@ -168,11 +247,41 @@ class PKIInstance(object):
efcdb2
                 self.group = m.group(1)
efcdb2
                 self.gid = grp.getgrnam(self.group).gr_gid
efcdb2
 
efcdb2
+        # load passwords
efcdb2
+        self.passwords.clear()
efcdb2
+        lines = open(self.password_conf).read().splitlines()
efcdb2
+
efcdb2
+        for line in lines:
efcdb2
+            parts = line.split('=', 1)
efcdb2
+            name = parts[0]
efcdb2
+            value = parts[1]
efcdb2
+            self.passwords[name] = value
efcdb2
+
efcdb2
+        # load subsystems
efcdb2
         for subsystem_name in os.listdir(self.registry_dir):
efcdb2
-            if subsystem_name in pki.server.SUBSYSTEM_TYPES:
efcdb2
-                subsystem = PKISubsystem(self, subsystem_name)
efcdb2
+            if subsystem_name in SUBSYSTEM_TYPES:
efcdb2
+                if subsystem_name in SUBSYSTEM_CLASSES:
efcdb2
+                    subsystem = SUBSYSTEM_CLASSES[subsystem_name](self)
efcdb2
+                else:
efcdb2
+                    subsystem = PKISubsystem(self, subsystem_name)
efcdb2
+                subsystem.load()
efcdb2
                 self.subsystems.append(subsystem)
efcdb2
 
efcdb2
+    def get_password(self, name):
efcdb2
+        if name in self.passwords:
efcdb2
+            return self.passwords[name]
efcdb2
+
efcdb2
+        password = getpass.getpass(prompt='Enter password for %s: ' % name)
efcdb2
+        self.passwords[name] = password
efcdb2
+
efcdb2
+        return password
efcdb2
+
efcdb2
+    def get_subsystem(self, name):
efcdb2
+        for subsystem in self.subsystems:
efcdb2
+            if name == subsystem.name:
efcdb2
+                return subsystem
efcdb2
+        return None
efcdb2
+
efcdb2
     def is_deployed(self, webapp_name):
efcdb2
         context_xml = os.path.join(
efcdb2
             self.conf_dir, 'Catalina', 'localhost', webapp_name + '.xml')
efcdb2
diff --git a/base/server/python/pki/server/ca.py b/base/server/python/pki/server/ca.py
efcdb2
new file mode 100644
efcdb2
index 0000000..70ebf4d
efcdb2
--- /dev/null
efcdb2
+++ b/base/server/python/pki/server/ca.py
efcdb2
@@ -0,0 +1,92 @@
efcdb2
+#!/usr/bin/python
efcdb2
+# Authors:
efcdb2
+#     Endi S. Dewata <edewata@redhat.com>
efcdb2
+#
efcdb2
+# This program is free software; you can redistribute it and/or modify
efcdb2
+# it under the terms of the GNU General Public License as published by
efcdb2
+# the Free Software Foundation; version 2 of the License.
efcdb2
+#
efcdb2
+# This program is distributed in the hope that it will be useful,
efcdb2
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
efcdb2
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
efcdb2
+# GNU General Public License for more details.
efcdb2
+#
efcdb2
+# You should have received a copy of the GNU General Public License along
efcdb2
+# with this program; if not, write to the Free Software Foundation, Inc.,
efcdb2
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
efcdb2
+#
efcdb2
+# Copyright (C) 2015 Red Hat, Inc.
efcdb2
+# All rights reserved.
efcdb2
+#
efcdb2
+
efcdb2
+from __future__ import absolute_import
efcdb2
+import ldap
efcdb2
+import ldap.filter
efcdb2
+
efcdb2
+import pki
efcdb2
+import pki.server
efcdb2
+
efcdb2
+
efcdb2
+class CASubsystem(pki.server.PKISubsystem):
efcdb2
+
efcdb2
+    def __init__(self, instance):
efcdb2
+        super(CASubsystem, self).__init__(instance, 'ca')
efcdb2
+
efcdb2
+    def find_cert_requests(self, cert=None):
efcdb2
+
efcdb2
+        base_dn = self.config['internaldb.basedn']
efcdb2
+
efcdb2
+        if cert:
efcdb2
+            escaped_value = ldap.filter.escape_filter_chars(cert)
efcdb2
+            search_filter = '(extdata-req--005fissued--005fcert=%s)' % escaped_value
efcdb2
+
efcdb2
+        else:
efcdb2
+            search_filter = '(objectClass=*)'
efcdb2
+
efcdb2
+        con = self.open_database()
efcdb2
+
efcdb2
+        entries = con.search_s(
efcdb2
+            'ou=ca,ou=requests,%s' % base_dn,
efcdb2
+            ldap.SCOPE_ONELEVEL,
efcdb2
+            search_filter,
efcdb2
+            None)
efcdb2
+
efcdb2
+        con.unbind_s()
efcdb2
+
efcdb2
+        requests = []
efcdb2
+        for entry in entries:
efcdb2
+            requests.append(self.create_request_object(entry))
efcdb2
+
efcdb2
+        return requests
efcdb2
+
efcdb2
+    def get_cert_requests(self, request_id):
efcdb2
+
efcdb2
+        base_dn = self.config['internaldb.basedn']
efcdb2
+
efcdb2
+        con = self.open_database()
efcdb2
+
efcdb2
+        entries = con.search_s(
efcdb2
+            'cn=%s,ou=ca,ou=requests,%s' % (request_id, base_dn),
efcdb2
+            ldap.SCOPE_BASE,
efcdb2
+            '(objectClass=*)',
efcdb2
+            None)
efcdb2
+
efcdb2
+        con.unbind_s()
efcdb2
+
efcdb2
+        entry = entries[0]
efcdb2
+        return self.create_request_object(entry)
efcdb2
+
efcdb2
+    def create_request_object(self, entry):
efcdb2
+
efcdb2
+        attrs = entry[1]
efcdb2
+
efcdb2
+        request = {}
efcdb2
+        request['id'] = attrs['cn'][0]
efcdb2
+        request['type'] = attrs['requestType'][0]
efcdb2
+        request['status'] = attrs['requestState'][0]
efcdb2
+        request['request'] = attrs['extdata-cert--005frequest'][0]
efcdb2
+
efcdb2
+        return request
efcdb2
+
efcdb2
+
efcdb2
+pki.server.SUBSYSTEM_CLASSES['ca'] = CASubsystem
efcdb2
diff --git a/base/server/python/pki/server/cli/ca.py b/base/server/python/pki/server/cli/ca.py
efcdb2
new file mode 100644
efcdb2
index 0000000..2ad8652
efcdb2
--- /dev/null
efcdb2
+++ b/base/server/python/pki/server/cli/ca.py
efcdb2
@@ -0,0 +1,206 @@
efcdb2
+#!/usr/bin/python
efcdb2
+# Authors:
efcdb2
+#     Endi S. Dewata <edewata@redhat.com>
efcdb2
+#
efcdb2
+# This program is free software; you can redistribute it and/or modify
efcdb2
+# it under the terms of the GNU General Public License as published by
efcdb2
+# the Free Software Foundation; version 2 of the License.
efcdb2
+#
efcdb2
+# This program is distributed in the hope that it will be useful,
efcdb2
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
efcdb2
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
efcdb2
+# GNU General Public License for more details.
efcdb2
+#
efcdb2
+# You should have received a copy of the GNU General Public License along
efcdb2
+# with this program; if not, write to the Free Software Foundation, Inc.,
efcdb2
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
efcdb2
+#
efcdb2
+# Copyright (C) 2015 Red Hat, Inc.
efcdb2
+# All rights reserved.
efcdb2
+#
efcdb2
+
efcdb2
+from __future__ import absolute_import
efcdb2
+from __future__ import print_function
efcdb2
+import getopt
efcdb2
+import io
efcdb2
+import sys
efcdb2
+
efcdb2
+import pki.cli
efcdb2
+import pki.server.ca
efcdb2
+
efcdb2
+
efcdb2
+class CACLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(CACLI, self).__init__(
efcdb2
+            'ca', 'CA management commands')
efcdb2
+
efcdb2
+        self.add_module(CACertCLI())
efcdb2
+
efcdb2
+
efcdb2
+class CACertCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(CACertCLI, self).__init__(
efcdb2
+            'cert', 'CA certificates management commands')
efcdb2
+
efcdb2
+        self.add_module(CACertRequestCLI())
efcdb2
+
efcdb2
+
efcdb2
+class CACertRequestCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(CACertRequestCLI, self).__init__(
efcdb2
+            'request', 'CA certificate requests management commands')
efcdb2
+
efcdb2
+        self.add_module(CACertRequestFindCLI())
efcdb2
+        self.add_module(CACertRequestShowCLI())
efcdb2
+
efcdb2
+    @staticmethod
efcdb2
+    def print_request(request, details=False):
efcdb2
+        print('  Request ID: %s' % request['id'])
efcdb2
+        print('  Type: %s' % request['type'])
efcdb2
+        print('  Status: %s' % request['status'])
efcdb2
+
efcdb2
+        if details:
efcdb2
+            print('  Request: %s' % request['request'])
efcdb2
+
efcdb2
+
efcdb2
+class CACertRequestFindCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(CACertRequestFindCLI, self).__init__(
efcdb2
+            'find', 'Find CA certificate requests')
efcdb2
+
efcdb2
+    def usage(self):
efcdb2
+        print('Usage: pki-server ca-cert-request-find [OPTIONS]')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('      --cert                      Issued certificate.')
efcdb2
+        print('      --cert-file                 File containing issued certificate.')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
+
efcdb2
+    def execute(self, args):
efcdb2
+
efcdb2
+        try:
efcdb2
+            opts, _ = getopt.gnu_getopt(args, 'i:v', [
efcdb2
+                'instance=', 'cert=', 'cert-file=',
efcdb2
+                'verbose', 'help'])
efcdb2
+
efcdb2
+        except getopt.GetoptError as e:
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
+        cert = None
efcdb2
+
efcdb2
+        for o, a in opts:
efcdb2
+            if o in ('-i', '--instance'):
efcdb2
+                instance_name = a
efcdb2
+
efcdb2
+            elif o == '--cert':
efcdb2
+                cert = a
efcdb2
+
efcdb2
+            elif o == '--cert-file':
efcdb2
+                with io.open(a, 'rb') as f:
efcdb2
+                    cert = f.read()
efcdb2
+
efcdb2
+            elif o in ('-v', '--verbose'):
efcdb2
+                self.set_verbose(True)
efcdb2
+
efcdb2
+            elif o == '--help':
efcdb2
+                self.print_help()
efcdb2
+                sys.exit()
efcdb2
+
efcdb2
+            else:
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
+                self.usage()
efcdb2
+                sys.exit(1)
efcdb2
+
efcdb2
+        instance = pki.server.PKIInstance(instance_name)
efcdb2
+        instance.load()
efcdb2
+
efcdb2
+        subsystem = instance.get_subsystem('ca')
efcdb2
+        results = subsystem.find_cert_requests(cert=cert)
efcdb2
+
efcdb2
+        self.print_message('%s entries matched' % len(results))
efcdb2
+
efcdb2
+        first = True
efcdb2
+        for request in results:
efcdb2
+            if first:
efcdb2
+                first = False
efcdb2
+            else:
efcdb2
+                print()
efcdb2
+
efcdb2
+            CACertRequestCLI.print_request(request)
efcdb2
+
efcdb2
+
efcdb2
+class CACertRequestShowCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(CACertRequestShowCLI, self).__init__(
efcdb2
+            'show', 'Show CA certificate request')
efcdb2
+
efcdb2
+    def usage(self):
efcdb2
+        print('Usage: pki-server ca-cert-request-show <request ID> [OPTIONS]')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
+
efcdb2
+    def execute(self, args):
efcdb2
+
efcdb2
+        try:
efcdb2
+            opts, args = getopt.gnu_getopt(args, 'i:v', [
efcdb2
+                'instance=', 'output-file=',
efcdb2
+                'verbose', 'help'])
efcdb2
+
efcdb2
+        except getopt.GetoptError as e:
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) != 1:
efcdb2
+            print('ERROR: missing request ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        request_id = args[0]
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
+        output_file = None
efcdb2
+
efcdb2
+        for o, a in opts:
efcdb2
+            if o in ('-i', '--instance'):
efcdb2
+                instance_name = a
efcdb2
+
efcdb2
+            elif o == '--output-file':
efcdb2
+                output_file = a
efcdb2
+
efcdb2
+            elif o in ('-v', '--verbose'):
efcdb2
+                self.set_verbose(True)
efcdb2
+
efcdb2
+            elif o == '--help':
efcdb2
+                self.print_help()
efcdb2
+                sys.exit()
efcdb2
+
efcdb2
+            else:
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
+                self.usage()
efcdb2
+                sys.exit(1)
efcdb2
+
efcdb2
+        instance = pki.server.PKIInstance(instance_name)
efcdb2
+        instance.load()
efcdb2
+
efcdb2
+        subsystem = instance.get_subsystem('ca')
efcdb2
+        request = subsystem.get_cert_requests(request_id)
efcdb2
+
efcdb2
+        if output_file:
efcdb2
+            with io.open(output_file, 'wb') as f:
efcdb2
+                f.write(request['request'])
efcdb2
+
efcdb2
+        else:
efcdb2
+            CACertRequestCLI.print_request(request, details=True)
efcdb2
diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
efcdb2
index 43eb564..fc89c27 100644
efcdb2
--- a/base/server/python/pki/server/cli/subsystem.py
efcdb2
+++ b/base/server/python/pki/server/cli/subsystem.py
efcdb2
@@ -19,8 +19,12 @@
efcdb2
 # All rights reserved.
efcdb2
 #
efcdb2
 
efcdb2
+from __future__ import absolute_import
efcdb2
+from __future__ import print_function
efcdb2
+import base64
efcdb2
 import getopt
efcdb2
-import os
efcdb2
+import nss.nss as nss
efcdb2
+import string
efcdb2
 import sys
efcdb2
 
efcdb2
 import pki.cli
efcdb2
@@ -38,11 +42,13 @@ class SubsystemCLI(pki.cli.CLI):
efcdb2
         self.add_module(SubsystemFindCLI())
efcdb2
         self.add_module(SubsystemShowCLI())
efcdb2
 
efcdb2
+        self.add_module(SubsystemCertCLI())
efcdb2
+
efcdb2
     @staticmethod
efcdb2
     def print_subsystem(subsystem):
efcdb2
-        print '  Subsystem ID: %s' % subsystem.name
efcdb2
-        print '  Instance ID: %s' % subsystem.instance.name
efcdb2
-        print '  Enabled: %s' % subsystem.is_enabled()
efcdb2
+        print('  Subsystem ID: %s' % subsystem.name)
efcdb2
+        print('  Instance ID: %s' % subsystem.instance.name)
efcdb2
+        print('  Enabled: %s' % subsystem.is_enabled())
efcdb2
 
efcdb2
 
efcdb2
 class SubsystemFindCLI(pki.cli.CLI):
efcdb2
@@ -51,12 +57,12 @@ class SubsystemFindCLI(pki.cli.CLI):
efcdb2
         super(SubsystemFindCLI, self).__init__('find', 'Find subsystems')
efcdb2
 
efcdb2
     def usage(self):
efcdb2
-        print 'Usage: pki-server subsystem-find [OPTIONS]'
efcdb2
-        print
efcdb2
-        print '  -i, --instance <instance ID>    Instance ID.'
efcdb2
-        print '  -v, --verbose                   Run in verbose mode.'
efcdb2
-        print '      --help                      Show help message.'
efcdb2
-        print
efcdb2
+        print('Usage: pki-server subsystem-find [OPTIONS]')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
 
efcdb2
     def execute(self, args):
efcdb2
 
efcdb2
@@ -66,11 +72,11 @@ class SubsystemFindCLI(pki.cli.CLI):
efcdb2
                 'verbose', 'help'])
efcdb2
 
efcdb2
         except getopt.GetoptError as e:
efcdb2
-            print 'ERROR: ' + str(e)
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
-        instance_name = None
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
 
efcdb2
         for o, a in opts:
efcdb2
             if o in ('-i', '--instance'):
efcdb2
@@ -84,32 +90,17 @@ class SubsystemFindCLI(pki.cli.CLI):
efcdb2
                 sys.exit()
efcdb2
 
efcdb2
             else:
efcdb2
-                print 'ERROR: unknown option ' + o
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
                 self.usage()
efcdb2
                 sys.exit(1)
efcdb2
 
efcdb2
-        if not instance_name:
efcdb2
-            print 'ERROR: missing instance ID'
efcdb2
-            self.usage()
efcdb2
-            sys.exit(1)
efcdb2
-
efcdb2
         instance = pki.server.PKIInstance(instance_name)
efcdb2
         instance.load()
efcdb2
 
efcdb2
-        results = []
efcdb2
-
efcdb2
-        for name in os.listdir(instance.base_dir):
efcdb2
-
efcdb2
-            subsystem = pki.server.PKISubsystem(instance, name)
efcdb2
-            if not subsystem.is_valid():
efcdb2
-                continue
efcdb2
-
efcdb2
-            results.append(subsystem)
efcdb2
-
efcdb2
-        self.print_message('%s entries matched' % len(results))
efcdb2
+        self.print_message('%s entries matched' % len(instance.subsystems))
efcdb2
 
efcdb2
         first = True
efcdb2
-        for subsystem in results:
efcdb2
+        for subsystem in instance.subsystems:
efcdb2
             if first:
efcdb2
                 first = False
efcdb2
             else:
efcdb2
@@ -124,12 +115,12 @@ class SubsystemShowCLI(pki.cli.CLI):
efcdb2
         super(SubsystemShowCLI, self).__init__('show', 'Show subsystem')
efcdb2
 
efcdb2
     def usage(self):
efcdb2
-        print 'Usage: pki-server subsystem-show [OPTIONS] <subsystem ID>'
efcdb2
-        print
efcdb2
-        print '  -i, --instance <instance ID>    Instance ID.'
efcdb2
-        print '  -v, --verbose                   Run in verbose mode.'
efcdb2
-        print '      --help                      Show help message.'
efcdb2
-        print
efcdb2
+        print('Usage: pki-server subsystem-show [OPTIONS] <subsystem ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
 
efcdb2
     def execute(self, argv):
efcdb2
 
efcdb2
@@ -139,17 +130,17 @@ class SubsystemShowCLI(pki.cli.CLI):
efcdb2
                 'verbose', 'help'])
efcdb2
 
efcdb2
         except getopt.GetoptError as e:
efcdb2
-            print 'ERROR: ' + str(e)
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         if len(args) != 1:
efcdb2
-            print 'ERROR: missing subsystem ID'
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         subsystem_name = args[0]
efcdb2
-        instance_name = None
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
 
efcdb2
         for o, a in opts:
efcdb2
             if o in ('-i', '--instance'):
efcdb2
@@ -163,19 +154,14 @@ class SubsystemShowCLI(pki.cli.CLI):
efcdb2
                 sys.exit()
efcdb2
 
efcdb2
             else:
efcdb2
-                print 'ERROR: unknown option ' + o
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
                 self.usage()
efcdb2
                 sys.exit(1)
efcdb2
 
efcdb2
-        if not instance_name:
efcdb2
-            print 'ERROR: missing instance ID'
efcdb2
-            self.usage()
efcdb2
-            sys.exit(1)
efcdb2
-
efcdb2
         instance = pki.server.PKIInstance(instance_name)
efcdb2
         instance.load()
efcdb2
 
efcdb2
-        subsystem = pki.server.PKISubsystem(instance, subsystem_name)
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
 
efcdb2
         SubsystemCLI.print_subsystem(subsystem)
efcdb2
 
efcdb2
@@ -186,12 +172,12 @@ class SubsystemEnableCLI(pki.cli.CLI):
efcdb2
         super(SubsystemEnableCLI, self).__init__('enable', 'Enable subsystem')
efcdb2
 
efcdb2
     def usage(self):
efcdb2
-        print 'Usage: pki-server subsystem-enable [OPTIONS] <subsystem ID>'
efcdb2
-        print
efcdb2
-        print '  -i, --instance <instance ID>    Instance ID.'
efcdb2
-        print '  -v, --verbose                   Run in verbose mode.'
efcdb2
-        print '      --help                      Show help message.'
efcdb2
-        print
efcdb2
+        print('Usage: pki-server subsystem-enable [OPTIONS] <subsystem ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
 
efcdb2
     def execute(self, argv):
efcdb2
 
efcdb2
@@ -201,17 +187,17 @@ class SubsystemEnableCLI(pki.cli.CLI):
efcdb2
                 'verbose', 'help'])
efcdb2
 
efcdb2
         except getopt.GetoptError as e:
efcdb2
-            print 'ERROR: ' + str(e)
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         if len(args) != 1:
efcdb2
-            print 'ERROR: missing subsystem ID'
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         subsystem_name = args[0]
efcdb2
-        instance_name = None
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
 
efcdb2
         for o, a in opts:
efcdb2
             if o in ('-i', '--instance'):
efcdb2
@@ -225,19 +211,14 @@ class SubsystemEnableCLI(pki.cli.CLI):
efcdb2
                 sys.exit()
efcdb2
 
efcdb2
             else:
efcdb2
-                print 'ERROR: unknown option ' + o
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
                 self.usage()
efcdb2
                 sys.exit(1)
efcdb2
 
efcdb2
-        if not instance_name:
efcdb2
-            print 'ERROR: missing instance ID'
efcdb2
-            self.usage()
efcdb2
-            sys.exit(1)
efcdb2
-
efcdb2
         instance = pki.server.PKIInstance(instance_name)
efcdb2
         instance.load()
efcdb2
 
efcdb2
-        subsystem = pki.server.PKISubsystem(instance, subsystem_name)
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
         subsystem.enable()
efcdb2
 
efcdb2
         self.print_message('Enabled "%s" subsystem' % subsystem_name)
efcdb2
@@ -251,12 +232,12 @@ class SubsystemDisableCLI(pki.cli.CLI):
efcdb2
         super(SubsystemDisableCLI, self).__init__('disable', 'Disable subsystem')
efcdb2
 
efcdb2
     def usage(self):
efcdb2
-        print 'Usage: pki-server subsystem-disable [OPTIONS] <subsystem ID>'
efcdb2
-        print
efcdb2
-        print '  -i, --instance <instance ID>    Instance ID.'
efcdb2
-        print '  -v, --verbose                   Run in verbose mode.'
efcdb2
-        print '      --help                      Show help message.'
efcdb2
-        print
efcdb2
+        print('Usage: pki-server subsystem-disable [OPTIONS] <subsystem ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
 
efcdb2
     def execute(self, argv):
efcdb2
 
efcdb2
@@ -266,17 +247,17 @@ class SubsystemDisableCLI(pki.cli.CLI):
efcdb2
                 'verbose', 'help'])
efcdb2
 
efcdb2
         except getopt.GetoptError as e:
efcdb2
-            print 'ERROR: ' + str(e)
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         if len(args) != 1:
efcdb2
-            print 'ERROR: missing subsystem ID'
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
             self.usage()
efcdb2
             sys.exit(1)
efcdb2
 
efcdb2
         subsystem_name = args[0]
efcdb2
-        instance_name = None
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
 
efcdb2
         for o, a in opts:
efcdb2
             if o in ('-i', '--instance'):
efcdb2
@@ -290,21 +271,267 @@ class SubsystemDisableCLI(pki.cli.CLI):
efcdb2
                 sys.exit()
efcdb2
 
efcdb2
             else:
efcdb2
-                print 'ERROR: unknown option ' + o
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
                 self.usage()
efcdb2
                 sys.exit(1)
efcdb2
 
efcdb2
-        if not instance_name:
efcdb2
-            print 'ERROR: missing instance ID'
efcdb2
-            self.usage()
efcdb2
-            sys.exit(1)
efcdb2
-
efcdb2
         instance = pki.server.PKIInstance(instance_name)
efcdb2
         instance.load()
efcdb2
 
efcdb2
-        subsystem = pki.server.PKISubsystem(instance, subsystem_name)
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
         subsystem.disable()
efcdb2
 
efcdb2
         self.print_message('Disabled "%s" subsystem' % subsystem_name)
efcdb2
 
efcdb2
         SubsystemCLI.print_subsystem(subsystem)
efcdb2
+
efcdb2
+
efcdb2
+class SubsystemCertCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(SubsystemCertCLI, self).__init__(
efcdb2
+            'cert', 'Subsystem certificate management commands')
efcdb2
+
efcdb2
+        self.add_module(SubsystemCertFindCLI())
efcdb2
+        self.add_module(SubsystemCertShowCLI())
efcdb2
+        self.add_module(SubsystemCertUpdateCLI())
efcdb2
+
efcdb2
+    @staticmethod
efcdb2
+    def print_subsystem_cert(cert):
efcdb2
+        print('  Cert ID: %s' % cert['id'])
efcdb2
+        print('  Nickname: %s' % cert['nickname'])
efcdb2
+        print('  Token: %s' % cert['token'])
efcdb2
+        print('  Certificate: %s' % cert['data'])
efcdb2
+        print('  Request: %s' % cert['request'])
efcdb2
+
efcdb2
+
efcdb2
+class SubsystemCertFindCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(SubsystemCertFindCLI, self).__init__(
efcdb2
+            'find', 'Find subsystem certificates')
efcdb2
+
efcdb2
+    def usage(self):
efcdb2
+        print('Usage: pki-server subsystem-cert-find [OPTIONS] <subsystem ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
+
efcdb2
+    def execute(self, argv):
efcdb2
+
efcdb2
+        try:
efcdb2
+            opts, args = getopt.getopt(argv, 'i:v', [
efcdb2
+                'instance=',
efcdb2
+                'verbose', 'help'])
efcdb2
+
efcdb2
+        except getopt.GetoptError as e:
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) != 1:
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        subsystem_name = args[0]
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
+
efcdb2
+        for o, a in opts:
efcdb2
+            if o in ('-i', '--instance'):
efcdb2
+                instance_name = a
efcdb2
+
efcdb2
+            elif o in ('-v', '--verbose'):
efcdb2
+                self.set_verbose(True)
efcdb2
+
efcdb2
+            elif o == '--help':
efcdb2
+                self.print_help()
efcdb2
+                sys.exit()
efcdb2
+
efcdb2
+            else:
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
+                self.usage()
efcdb2
+                sys.exit(1)
efcdb2
+
efcdb2
+        instance = pki.server.PKIInstance(instance_name)
efcdb2
+        instance.load()
efcdb2
+
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
+        results = subsystem.find_subsystem_certs()
efcdb2
+
efcdb2
+        self.print_message('%s entries matched' % len(results))
efcdb2
+
efcdb2
+        first = True
efcdb2
+        for cert in results:
efcdb2
+            if first:
efcdb2
+                first = False
efcdb2
+            else:
efcdb2
+                print()
efcdb2
+
efcdb2
+            SubsystemCertCLI.print_subsystem_cert(cert)
efcdb2
+
efcdb2
+
efcdb2
+class SubsystemCertShowCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(SubsystemCertShowCLI, self).__init__(
efcdb2
+            'show', 'Show subsystem certificate')
efcdb2
+
efcdb2
+    def usage(self):
efcdb2
+        print('Usage: pki-server subsystem-cert-show [OPTIONS] <subsystem ID> <cert ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
+
efcdb2
+    def execute(self, argv):
efcdb2
+
efcdb2
+        try:
efcdb2
+            opts, args = getopt.getopt(argv, 'i:v', [
efcdb2
+                'instance=',
efcdb2
+                'verbose', 'help'])
efcdb2
+
efcdb2
+        except getopt.GetoptError as e:
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) < 1:
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) < 2:
efcdb2
+            print('ERROR: missing cert ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        subsystem_name = args[0]
efcdb2
+        cert_id = args[1]
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
+
efcdb2
+        for o, a in opts:
efcdb2
+            if o in ('-i', '--instance'):
efcdb2
+                instance_name = a
efcdb2
+
efcdb2
+            elif o in ('-v', '--verbose'):
efcdb2
+                self.set_verbose(True)
efcdb2
+
efcdb2
+            elif o == '--help':
efcdb2
+                self.print_help()
efcdb2
+                sys.exit()
efcdb2
+
efcdb2
+            else:
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
+                self.usage()
efcdb2
+                sys.exit(1)
efcdb2
+
efcdb2
+        instance = pki.server.PKIInstance(instance_name)
efcdb2
+        instance.load()
efcdb2
+
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
+        subsystem_cert = subsystem.get_subsystem_cert(cert_id)
efcdb2
+
efcdb2
+        SubsystemCertCLI.print_subsystem_cert(subsystem_cert)
efcdb2
+
efcdb2
+
efcdb2
+class SubsystemCertUpdateCLI(pki.cli.CLI):
efcdb2
+
efcdb2
+    def __init__(self):
efcdb2
+        super(SubsystemCertUpdateCLI, self).__init__(
efcdb2
+            'update', 'Update subsystem certificate')
efcdb2
+
efcdb2
+    def usage(self):
efcdb2
+        print('Usage: pki-server subsystem-cert-update [OPTIONS] <subsystem ID> <cert ID>')
efcdb2
+        print()
efcdb2
+        print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
efcdb2
+        print('  -v, --verbose                   Run in verbose mode.')
efcdb2
+        print('      --help                      Show help message.')
efcdb2
+        print()
efcdb2
+
efcdb2
+    def execute(self, argv):
efcdb2
+
efcdb2
+        try:
efcdb2
+            opts, args = getopt.getopt(argv, 'i:v', [
efcdb2
+                'instance=',
efcdb2
+                'verbose', 'help'])
efcdb2
+
efcdb2
+        except getopt.GetoptError as e:
efcdb2
+            print('ERROR: ' + str(e))
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) < 1:
efcdb2
+            print('ERROR: missing subsystem ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        if len(args) < 2:
efcdb2
+            print('ERROR: missing cert ID')
efcdb2
+            self.usage()
efcdb2
+            sys.exit(1)
efcdb2
+
efcdb2
+        subsystem_name = args[0]
efcdb2
+        cert_id = args[1]
efcdb2
+        instance_name = 'pki-tomcat'
efcdb2
+
efcdb2
+        for o, a in opts:
efcdb2
+            if o in ('-i', '--instance'):
efcdb2
+                instance_name = a
efcdb2
+
efcdb2
+            elif o in ('-v', '--verbose'):
efcdb2
+                self.set_verbose(True)
efcdb2
+
efcdb2
+            elif o == '--help':
efcdb2
+                self.print_help()
efcdb2
+                sys.exit()
efcdb2
+
efcdb2
+            else:
efcdb2
+                print('ERROR: unknown option ' + o)
efcdb2
+                self.usage()
efcdb2
+                sys.exit(1)
efcdb2
+
efcdb2
+        instance = pki.server.PKIInstance(instance_name)
efcdb2
+        instance.load()
efcdb2
+
efcdb2
+        subsystem = instance.get_subsystem(subsystem_name)
efcdb2
+        subsystem_cert = subsystem.get_subsystem_cert(cert_id)
efcdb2
+
efcdb2
+        # get cert data from NSS database
efcdb2
+        nss.nss_init(instance.nssdb_dir)
efcdb2
+        nss_cert = nss.find_cert_from_nickname(subsystem_cert['nickname'])
efcdb2
+        data = base64.b64encode(nss_cert.der_data)
efcdb2
+        del nss_cert
efcdb2
+        nss.nss_shutdown()
efcdb2
+        subsystem_cert['data'] = data
efcdb2
+
efcdb2
+        # format cert data for LDAP database
efcdb2
+        lines = [data[i:i+64] for i in range(0, len(data), 64)]
efcdb2
+        data = string.join(lines, '\r\n') + '\r\n'
efcdb2
+
efcdb2
+        # get cert request from local CA
efcdb2
+        # TODO: add support for remote CA
efcdb2
+        ca = instance.get_subsystem('ca')
efcdb2
+        results = ca.find_cert_requests(cert=data)
efcdb2
+        cert_request = results[-1]
efcdb2
+        request = cert_request['request']
efcdb2
+
efcdb2
+        # format cert request for CS.cfg
efcdb2
+        lines = request.splitlines()
efcdb2
+        if lines[0] == '-----BEGIN CERTIFICATE REQUEST-----':
efcdb2
+            lines = lines[1:]
efcdb2
+        if lines[-1] == '-----END CERTIFICATE REQUEST-----':
efcdb2
+            lines = lines[:-1]
efcdb2
+        request = string.join(lines, '')
efcdb2
+        subsystem_cert['request'] = request
efcdb2
+
efcdb2
+        # store cert data and request in CS.cfg
efcdb2
+        subsystem.update_subsystem_cert(subsystem_cert)
efcdb2
+        subsystem.save()
efcdb2
+
efcdb2
+        self.print_message('Updated "%s" subsystem certificate' % cert_id)
efcdb2
+
efcdb2
+        SubsystemCertCLI.print_subsystem_cert(subsystem_cert)
efcdb2
diff --git a/base/server/python/pki/server/upgrade.py b/base/server/python/pki/server/upgrade.py
efcdb2
index c9426a0..f82ffe6 100644
efcdb2
--- a/base/server/python/pki/server/upgrade.py
efcdb2
+++ b/base/server/python/pki/server/upgrade.py
efcdb2
@@ -220,6 +220,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader):
efcdb2
         if self.subsystemName:
efcdb2
             subsystem = pki.server.PKISubsystem(instance, self.subsystemName)
efcdb2
             subsystem.validate()
efcdb2
+            subsystem.load()
efcdb2
             return [subsystem]
efcdb2
 
efcdb2
         subsystem_list = []
efcdb2
@@ -232,6 +233,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader):
efcdb2
                 if subsystemName in pki.server.SUBSYSTEM_TYPES:
efcdb2
                     subsystem = pki.server.PKISubsystem(instance, subsystemName)
efcdb2
                     subsystem.validate()
efcdb2
+                    subsystem.load()
efcdb2
                     subsystem_list.append(subsystem)
efcdb2
         else:
efcdb2
             for subsystemName in pki.server.SUBSYSTEM_TYPES:
efcdb2
@@ -242,6 +244,7 @@ class PKIServerUpgrader(pki.upgrade.PKIUpgrader):
efcdb2
                 if os.path.exists(registry_dir):
efcdb2
                     subsystem = pki.server.PKISubsystem(instance, subsystemName)
efcdb2
                     subsystem.validate()
efcdb2
+                    subsystem.load()
efcdb2
                     subsystem_list.append(subsystem)
efcdb2
 
efcdb2
         subsystem_list.sort()
efcdb2
diff --git a/base/server/sbin/pki-server b/base/server/sbin/pki-server
efcdb2
index 627a476..cdfd98e 100644
efcdb2
--- a/base/server/sbin/pki-server
efcdb2
+++ b/base/server/sbin/pki-server
efcdb2
@@ -23,6 +23,7 @@ import getopt
efcdb2
 import sys
efcdb2
 
efcdb2
 import pki.cli
efcdb2
+import pki.server.cli.ca
efcdb2
 import pki.server.cli.instance
efcdb2
 import pki.server.cli.subsystem
efcdb2
 import pki.server.cli.migrate
efcdb2
@@ -35,6 +36,7 @@ class PKIServerCLI(pki.cli.CLI):
efcdb2
 
efcdb2
         super(PKIServerCLI, self).__init__('pki-server', 'PKI server command-line interface')
efcdb2
 
efcdb2
+        self.add_module(pki.server.cli.ca.CACLI())
efcdb2
         self.add_module(pki.server.cli.instance.InstanceCLI())
efcdb2
         self.add_module(pki.server.cli.subsystem.SubsystemCLI())
efcdb2
         self.add_module(pki.server.cli.migrate.MigrateCLI())