On 21/10/15 15:24, Simo Sorce wrote:
On 21/10/15 11:46, Martin Babinsky wrote:
On 10/20/2015 07:24 PM, Simo Sorce wrote:
On 20/10/15 06:32, Martin Babinsky wrote:
On 10/15/2015 08:14 PM, Simo Sorce wrote:
On 15/10/15 11:39, Martin Basti wrote:
Without this patch the ipa-ca-install is broken in current master.
Unexpected error - see /var/log/ipareplica-ca-install.log for
details:
AttributeError: Values instance has no attribute 'promote'

Should be fixed with the attached patches.



NACK, in patch 551 you add a test for non-existent CLI option into main
method:

@@ -198,10 +251,20 @@ def main():
      if os.geteuid() != 0:
          sys.exit("\nYou must be root to run this script.\n")

-    if filename is not None:
-        install_replica(safe_options, options, filename)
-    else:
-        install_master(safe_options, options)
+    try:
+        if options.replica or filename is not None:
+            install_replica(safe_options, options, filename)
+        else:
+            install_master(safe_options, options)
+
+    finally:
+        # Clean up if we created custom credentials
+        created_ccache_file = getattr(options, 'created_ccache_file',
None)
+        if created_ccache_file is not None:
+            try:
+                os.unlink(created_ccache_file)
+            except OSError:
+                pass

I guess you wanted to add '--replica' option to the CA installer but
since it was not added to option parser the installer explodes.

# ipa-ca-install

Your system may be partly configured.
Run /usr/sbin/ipa-server-install --uninstall to clean up.

Unexpected error - see /var/log/ipareplica-ca-install.log for details:
AttributeError: Values instance has no attribute 'replica'


The attached patch should address this problem now.

Simo.


Thanks, the patch enables CA install on promoted replica.

I have one minor nitpick though:

When running ipa-ca-install on domain level 0 replica w/o replica file,
the installer issues the following error:

# ipa-ca-install
Replica file None does not exist

I guess you should separately handle the case when no replica file is
specified and issue a corresponding error message like "A replica file
is required".

Done.
Simo.

Scratch this, it contains a typo, see attached.

Simo.

--
Simo Sorce * Red Hat, Inc * New York
>From 85cb09df61ace1f663f7ca4ee18f149c7f70601d Mon Sep 17 00:00:00 2001
From: Simo Sorce <s...@redhat.com>
Date: Thu, 20 Aug 2015 17:10:23 -0400
Subject: [PATCH] Allow ipa-ca-install to use the new promotion code

This makes it possible to install a CA after-the-fact on a server
that has been promoted (and has no replica file available).

Signed-off-by: Simo Sorce <s...@redhat.com>
---
 install/tools/ipa-ca-install | 134 ++++++++++++++++++++++++++++++-------------
 ipaserver/install/ca.py      |   2 -
 2 files changed, 94 insertions(+), 42 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 6564e4d0304d4e189b133c495b75f200b04e2988..192e3a6e1f635af64bd80af4a4ec616956b0a5e9 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -21,12 +21,16 @@
 import sys
 import os
 import shutil
+import tempfile
 from ipapython import ipautil
 
 from ipaserver.install import installutils
 from ipaserver.install import certs
 from ipaserver.install.installutils import create_replica_config
+from ipaserver.install.installutils import check_creds, ReplicaConfig
 from ipaserver.install import dsinstance, ca
+from ipaserver.install import cainstance, custodiainstance
+from ipapython import dogtag
 from ipapython import version
 from ipalib import api
 from ipapython.dn import DN
@@ -67,6 +71,8 @@ def parse_options():
                       type="choice",
                       choices=('SHA1withRSA', 'SHA256withRSA', 'SHA512withRSA'),
                       help="Signing algorithm of the IPA CA certificate")
+    parser.add_option("-P", "--principal", dest="principal", sensitive=True,
+                      default=None, help="User allowed to manage replicas")
 
     options, args = parser.parse_args()
     safe_options = parser.get_safe_opts(options)
@@ -101,20 +107,18 @@ def get_dirman_password():
 
 
 def install_replica(safe_options, options, filename):
-    standard_logging_setup(log_file_name, debug=options.debug)
-
-    root_logger.debug('%s was invoked with argument "%s" and options: %s',
-        sys.argv[0], filename, safe_options)
-    root_logger.debug('IPA version %s', version.VENDOR_VERSION)
-
-    if not ipautil.file_exists(filename):
-        sys.exit("Replica file %s does not exist" % filename)
-
-    if not dsinstance.DsInstance().is_configured():
-        sys.exit("IPA server is not configured on this system.\n")
-
-    api.bootstrap(in_server=True)
-    api.finalize()
+    domain_level = dsinstance.get_domain_level(api)
+    if domain_level > 0:
+        options.promote = True
+    else:
+        options.promote = False
+        if filename is None:
+            sys.exit("A replica file is required")
+        if not ipautil.file_exists(filename):
+            sys.exit("Replica file %s does not exist" % filename)
+
+    # Check if we have admin creds already, otherwise acquire them
+    check_creds(options, api.env.realm)
 
     # get the directory manager password
     dirman_password = options.password
@@ -132,13 +136,36 @@ def install_replica(safe_options, options, filename):
             options.unattended:
         sys.exit('admin password required')
 
-    config = create_replica_config(dirman_password, filename, options)
+    if options.promote:
+        config = ReplicaConfig()
+        config.master_host_name = None
+        config.realm_name = api.env.realm
+        config.host_name = api.env.host
+        config.domain_name = api.env.domain
+        config.dirman_password = dirman_password
+        config.ca_ds_port = dogtag.install_constants.DS_PORT
+        config.top_dir = tempfile.mkdtemp("ipa")
+        config.dir = config.top_dir
+    else:
+        config = create_replica_config(dirman_password, filename, options)
+
     global REPLICA_INFO_TOP_DIR
     REPLICA_INFO_TOP_DIR = config.top_dir
     config.setup_ca = True
 
-    api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
-                              bind_pw=dirman_password)
+    conn = api.Backend.ldap2
+    conn.connect(bind_dn=DN(('cn', 'Directory Manager')),
+                            bind_pw=dirman_password)
+
+    if config.subject_base is None:
+        attrs = conn.get_ipa_config()
+        config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
+
+    if config.master_host_name is None:
+        config.ca_host_name = cainstance.find_ca_server(api.env.ca_host, conn)
+        config.master_host_name = config.ca_host_name
+    else:
+        config.ca_host_name = config.master_host_name
 
     options.realm_name = config.realm_name
     options.domain_name = config.domain_name
@@ -147,24 +174,25 @@ def install_replica(safe_options, options, filename):
     options.subject = config.subject_base
 
     ca.install_check(True, config, options)
-    ca.install(True, config, options)
+    if options.promote:
+        ca_data = (os.path.join(config.dir, 'cacert.p12'),
+                   config.dirman_password)
+        custodia = custodiainstance.CustodiaInstance(config.host_name,
+                                                     config.realm_name)
+        custodia.get_ca_keys(config.ca_host_name, ca_data[0], ca_data[1])
+
+        CA = cainstance.CAInstance(config.realm_name, certs.NSS_DIR,
+                                   dogtag_constants=dogtag.install_constants,
+                                   host_name=config.host_name,
+                                   dm_password=config.dirman_password)
+        CA.configure_replica(config.ca_host_name,
+                             subject_base=config.subject_base,
+                             ca_cert_bundle=ca_data)
+    else:
+        ca.install(True, config, options)
 
 
 def install_master(safe_options, options):
-    standard_logging_setup(paths.IPASERVER_CA_INSTALL_LOG, debug=options.debug)
-
-    root_logger.debug(
-        "%s was invoked with options: %s", sys.argv[0], safe_options)
-    root_logger.debug("IPA version %s", version.VENDOR_VERSION)
-
-    if not dsinstance.DsInstance().is_configured():
-        sys.exit("IPA server is not configured on this system.\n")
-
-    # override ra_plugin setting read from default.conf so that we have
-    # functional dogtag backend plugins during CA install
-    api.bootstrap(in_server=True, ra_plugin='dogtag')
-    api.finalize()
-
     dm_password = options.password
     if not dm_password:
         if options.unattended:
@@ -198,10 +226,37 @@ def main():
     if os.geteuid() != 0:
         sys.exit("\nYou must be root to run this script.\n")
 
-    if filename is not None:
-        install_replica(safe_options, options, filename)
-    else:
-        install_master(safe_options, options)
+    if not dsinstance.DsInstance().is_configured():
+        sys.exit("IPA server is not configured on this system.\n")
+
+    standard_logging_setup(paths.IPASERVER_CA_INSTALL_LOG, debug=options.debug)
+    root_logger.debug("%s was invoked with options: %s,%s",
+                      sys.argv[0], safe_options, filename)
+    root_logger.debug("IPA version %s", version.VENDOR_VERSION)
+
+    # override ra_plugin setting read from default.conf so that we have
+    # functional dogtag backend plugins during CA install
+    api.bootstrap(in_server=True, ra_plugin='dogtag')
+    api.finalize()
+
+    try:
+        conn = api.Backend.ldap2
+        conn.connect(autobind=True)
+        ca_host = service.find_providing_server('CA', conn)
+        conn.disconnect()
+        if ca_host is None:
+            install_master(safe_options, options)
+        else:
+            install_replica(safe_options, options, filename)
+
+    finally:
+        # Clean up if we created custom credentials
+        created_ccache_file = getattr(options, 'created_ccache_file', None)
+        if created_ccache_file is not None:
+            try:
+                os.unlink(created_ccache_file)
+            except OSError:
+                pass
 
 fail_message = '''
 Your system may be partly configured.
@@ -210,10 +265,9 @@ Run /usr/sbin/ipa-server-install --uninstall to clean up.
 
 if __name__ == '__main__':
     try:
-        with ipautil.private_ccache():
-            installutils.run_script(main, log_file_name=log_file_name,
-                                    operation_name='ipa-ca-install',
-                                    fail_message=fail_message)
+        installutils.run_script(main, log_file_name=log_file_name,
+                                operation_name='ipa-ca-install',
+                                fail_message=fail_message)
     finally:
         # always try to remove decrypted replica file
         try:
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 3eb9208c035002dce9c2a7faf3ebd3be935d2752..303a9da6f69d09a6337c6f4c3445a9f111a236b2 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -39,8 +39,6 @@ def install_check(standalone, replica_config, options):
 
         if standalone and not options.skip_conncheck:
             principal = options.principal
-            if principal is None:
-                principal = "admin"
             replica_conn_check(
                 replica_config.master_host_name, host_name, realm_name, True,
                 replica_config.ca_ds_port, options.admin_password,
-- 
2.4.3

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to