I did not test the external CA case when we merged DS instances some time ago, so it ended up broken. Here is a fix.


Our DsInstance class could only be initialized properly by calling create_instance or create_replica. Fr step 2, when the DS is not being installed, I gathered the common setup code to init_info, and called that. Ideally this will one day end up in __init__, but that's for a bigger refactoring.


https://fedorahosted.org/freeipa/ticket/3459

--
PetrĀ³
From 56ccdc78264e15bc2b36982d51548240afd2419b Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Mon, 25 Feb 2013 17:15:23 +0100
Subject: [PATCH] Fix installing server with external CA

Reorganize ipa-server-instal so that DS (and NTP server) installation
only happens in step one.

Change CAInstance to behave correctly in two-step install.

Add an `init_info` method to DSInstance that includes common
attribute/sub_dict initialization from create_instance and create_replica.
Use it in ipa-server-install to get a properly configured DSInstance
for later tasks.

https://fedorahosted.org/freeipa/ticket/3459
---
 install/tools/ipa-server-install | 76 ++++++++++++++++++++++------------------
 ipaserver/install/cainstance.py  | 18 +++++-----
 ipaserver/install/dsinstance.py  | 55 ++++++++++++++---------------
 3 files changed, 79 insertions(+), 70 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 15591071b0983511394a2cba3d829e1b84fe328e..57511c2147e52c78b1da894a7d7e83e9cb974acf 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -691,6 +691,15 @@ def main():
                 sys.exit(1)
             cert = certdict[certissuer]
 
+    # Figure out what external CA step we're in. See cainstance.py for more
+    # info on the 3 states.
+    if options.external_cert_file:
+        external = 2
+    elif options.external_ca:
+        external = 1
+    else:
+        external = 0
+
     print "=============================================================================="
     print "This program will set up the FreeIPA Server."
     print ""
@@ -717,8 +726,9 @@ def main():
     print "To accept the default shown in brackets, press the Enter key."
     print ""
 
-    # Make sure the 389-ds ports are available
-    check_dirsrv(options.unattended)
+    if external != 2:
+        # Make sure the 389-ds ports are available
+        check_dirsrv(options.unattended)
 
     if options.conf_ntp:
         try:
@@ -921,36 +931,43 @@ def main():
         except ipautil.CalledProcessError, e:
             root_logger.critical("failed to add DS group: %s" % e)
 
-    # Configure ntpd
-    if options.conf_ntp:
-        ipaclient.ntpconf.force_ntpd(sstore)
-        ntp = ntpinstance.NTPInstance(fstore)
-        if not ntp.is_configured():
-            ntp.create_instance()
-
-    # Create a directory server instance
-    ds = dsinstance.DsInstance(fstore=fstore)
-
     if options.dirsrv_pin:
         [pw_fd, pw_name] = tempfile.mkstemp()
         os.write(pw_fd, options.dirsrv_pin)
         os.close(pw_fd)
-
-    if options.dirsrv_pkcs12:
         pkcs12_info = (options.dirsrv_pkcs12, pw_name)
-        try:
+
+    if external != 2:
+        # Configure ntpd
+        if options.conf_ntp:
+            ipaclient.ntpconf.force_ntpd(sstore)
+            ntp = ntpinstance.NTPInstance(fstore)
+            if not ntp.is_configured():
+                ntp.create_instance()
+
+        # Create a directory server instance
+        ds = dsinstance.DsInstance(fstore=fstore)
+
+        if options.dirsrv_pkcs12:
+            try:
+                ds.create_instance(realm_name, host_name, domain_name,
+                                dm_password, pkcs12_info,
+                                subject_base=options.subject,
+                                hbac_allow=not options.hbac_allow)
+            finally:
+                os.remove(pw_name)
+        else:
             ds.create_instance(realm_name, host_name, domain_name,
-                               dm_password, pkcs12_info,
-                               subject_base=options.subject,
-                               hbac_allow=not options.hbac_allow)
-        finally:
-            os.remove(pw_name)
+                            dm_password, self_signed_ca=options.selfsign,
+                            idstart=options.idstart, idmax=options.idmax,
+                            subject_base=options.subject,
+                            hbac_allow=not options.hbac_allow)
     else:
-        ds.create_instance(realm_name, host_name, domain_name,
-                           dm_password, self_signed_ca=options.selfsign,
-                           idstart=options.idstart, idmax=options.idmax,
-                           subject_base=options.subject,
-                           hbac_allow=not options.hbac_allow)
+        ds = dsinstance.DsInstance(fstore=fstore)
+        ds.init_info(
+            realm_name, host_name, domain_name, dm_password,
+            options.selfsign, options.subject, 1101, 1100, None)
+
 
     if options.selfsign:
         ca = certs.CertDB(realm_name, host_name=host_name,
@@ -963,15 +980,6 @@ def main():
         except:
             pass
 
-        # Figure out what state we're in. See cainstance.py for more info on
-        # the 3 states.
-        if options.external_cert_file:
-            external = 2
-        elif options.external_ca:
-            external = 1
-        else:
-            external = 0
-
         if not dogtag.install_constants.SHARED_DB:
             cs = cainstance.CADSInstance(
                 host_name, realm_name, domain_name, dm_password)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index a1107cee87139f6248f3de3d6dc05a61e4804133..cba5fc9f642e8c4eb8f2610a6efdfeb044b3c899 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -238,8 +238,10 @@ def get_crl_files(path=None):
 def is_step_one_done():
     '''Read CS.cfg and determine if step one of an external CA install is done
     '''
-    test = installutils.get_directive(
-        dogtag.install_constants.CS_CFG_PATH, 'preop.ca.type', '=')
+    path = dogtag.install_constants.CS_CFG_PATH
+    if not os.path.exists(path):
+        return False
+    test = installutils.get_directive(path, 'preop.ca.type', '=')
     if test == "otherca":
         return True
     return False
@@ -736,16 +738,16 @@ class CAInstance(service.Service):
         finally:
             os.remove(cfg_file)
 
-        if not self.clone:
-            shutil.move("/root/.pki/pki-tomcat/ca_admin_cert.p12", \
-                        "/root/ca-agent.p12")
-        shutil.move("/var/lib/pki/pki-tomcat/alias/ca_backup_keys.p12", \
-                    "/root/cacert.p12")
-
         if self.external == 1:
             print "The next step is to get %s signed by your CA and re-run ipa-server-install as:" % self.csr_file
             print "ipa-server-install --external_cert_file=/path/to/signed_certificate --external_ca_file=/path/to/external_ca_certificate"
             sys.exit(0)
+        else:
+            if not self.clone:
+                shutil.move("/root/.pki/pki-tomcat/ca_admin_cert.p12", \
+                            "/root/ca-agent.p12")
+            shutil.move("/var/lib/pki/pki-tomcat/alias/ca_backup_keys.p12", \
+                        "/root/cacert.p12")
 
         root_logger.debug("completed creating ca instance")
 
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 77d76a635df9db1cec819d34aeade7456e77d966..25cac6c27143b2d17e19cb05d93666130d155c8b 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -228,24 +228,31 @@ class DsInstance(service.Service):
 
         self.step("configuring directory to start on boot", self.__enable)
 
+    def init_info(self, realm_name, fqdn, domain_name, dm_password,
+                  self_signed_ca, subject_base, idstart, idmax, pkcs12_info):
+        self.realm_name = realm_name.upper()
+        self.serverid = realm_to_serverid(self.realm_name)
+        self.suffix = ipautil.realm_to_suffix(self.realm_name)
+        self.fqdn = fqdn
+        self.dm_password = dm_password
+        self.domain = domain_name
+        self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name)
+        self.self_signed_ca = False
+        self.subject_base = subject_base
+        self.idstart = idstart
+        self.idmax = idmax
+        self.pkcs12_info = pkcs12_info
+
+        self.__setup_sub_dict()
+
     def create_instance(self, realm_name, fqdn, domain_name,
                         dm_password, pkcs12_info=None, self_signed_ca=False,
                         idstart=1100, idmax=999999, subject_base=None,
                         hbac_allow=True):
-        self.realm_name = realm_name.upper()
-        self.serverid = realm_to_serverid(self.realm_name)
-        self.suffix = ipautil.realm_to_suffix(self.realm_name)
-        self.fqdn = fqdn
-        self.dm_password = dm_password
-        self.domain = domain_name
-        self.pkcs12_info = pkcs12_info
-        self.self_signed_ca = self_signed_ca
-        self.idstart = idstart
-        self.idmax = idmax
-        self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name)
-        self.subject_base = subject_base
+        self.init_info(
+            realm_name, fqdn, domain_name, dm_password, self_signed_ca,
+            subject_base, idstart, idmax, pkcs12_info)
 
-        self.__setup_sub_dict()
         self.__common_setup()
 
         self.step("adding default layout", self.__add_default_layout)
@@ -266,26 +273,18 @@ class DsInstance(service.Service):
 
     def create_replica(self, realm_name, master_fqdn, fqdn,
                        domain_name, dm_password, pkcs12_info=None):
-        self.realm_name = realm_name.upper()
-        self.serverid = realm_to_serverid(self.realm_name)
-        self.suffix = ipautil.realm_to_suffix(self.realm_name)
-        self.master_fqdn = master_fqdn
-        self.fqdn = fqdn
-        self.dm_password = dm_password
-        self.domain = domain_name
-        self.pkcs12_info = pkcs12_info
-        self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name)
-
-        self.self_signed_ca = False
-        self.subject_base = None
         # idstart and idmax are configured so that the range is seen as
         # depleted by the DNA plugin and the replica will go and get a
         # new range from the master.
         # This way all servers use the initially defined range by default.
-        self.idstart = 1101
-        self.idmax = 1100
+        idstart = 1101
+        idmax = 1100
+
+        self.init_info(
+            realm_name, fqdn, domain_name, dm_password, None, None,
+            idstart, idmax, pkcs12_info)
+        self.master_fqdn = master_fqdn
 
-        self.__setup_sub_dict()
         self.__common_setup(True)
 
         self.step("setting up initial replication", self.__setup_replica)
-- 
1.8.1.4

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to