Hi,

the attached patch fixes <https://fedorahosted.org/freeipa/ticket/4039>.

Requires my patches 246 and 262 (current versions attached).

Honza

--
Jan Cholasta
>From 37deddbb4c80697460ef4af204e3a2e36dcbbe4e Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Mon, 24 Mar 2014 15:30:53 +0100
Subject: [PATCH 06/56] Add method for setting CA renewal master in LDAP to
 CAInstance.

Allow checking and setting CA renewal master for non-local CA instances.
---
 ipaserver/install/cainstance.py | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index f0aef75..7e2572d 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1609,12 +1609,15 @@ class CAInstance(service.Service):
             return True
         return False
 
-    def is_renewal_master(self):
+    def is_renewal_master(self, fqdn=None):
+        if fqdn is None:
+            fqdn = api.env.host
+
         if not self.admin_conn:
             self.ldap_connect()
 
-        dn = DN(('cn', 'CA'), ('cn', api.env.host), ('cn', 'masters'),
-                ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
+        dn = DN(('cn', 'CA'), ('cn', fqdn), ('cn', 'masters'), ('cn', 'ipa'),
+                ('cn', 'etc'), api.env.basedn)
         filter = '(ipaConfigString=caRenewalMaster)'
         try:
             self.admin_conn.get_entries(base_dn=dn, filter=filter,
@@ -1624,6 +1627,38 @@ class CAInstance(service.Service):
 
         return True
 
+    def set_renewal_master(self, fqdn=None):
+        if fqdn is None:
+            fqdn = api.env.host
+
+        if not self.admin_conn:
+            self.ldap_connect()
+
+        base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
+                     api.env.basedn)
+        filter = '(&(cn=CA)(ipaConfigString=caRenewalMaster))'
+        try:
+            entries = self.admin_conn.get_entries(
+                base_dn=base_dn, filter=filter, attrs_list=['ipaConfigString'])
+        except errors.NotFound:
+            entries = []
+
+        dn = DN(('cn', 'CA'), ('cn', fqdn), base_dn)
+        master_entry = self.admin_conn.get_entry(dn, ['ipaConfigString'])
+
+        for entry in entries:
+            if master_entry is not None and entry.dn == master_entry.dn:
+                master_entry = None
+                continue
+
+            entry['ipaConfigString'] = [x for x in entry['ipaConfigString']
+                                        if x.lower() != 'carenewalmaster']
+            self.admin_conn.update_entry(entry)
+
+        if master_entry is not None:
+            master_entry['ipaConfigString'].append('caRenewalMaster')
+            self.admin_conn.update_entry(master_entry)
+
 
 def replica_ca_install_check(config):
     if not config.setup_ca:
-- 
1.9.3

>From 8d9e84e14472d842d1b67452c9208131b76b2652 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 10 Apr 2014 14:14:10 +0200
Subject: [PATCH 14/56] Pick new CA renewal master when deleting a replica.

---
 install/tools/ipa-csreplica-manage | 10 ++++++++--
 install/tools/ipa-replica-manage   | 13 ++++++++++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index eb589f3..cfcb354 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -25,7 +25,8 @@ import os
 import krbV
 from ipapython.ipa_log_manager import *
 
-from ipaserver.install import replication, installutils, bindinstance
+from ipaserver.install import (replication, installutils, bindinstance,
+    cainstance, certs)
 from ipalib import api, errors, util
 from ipalib.constants import CACERT
 from ipapython import ipautil, ipaldap, version, dogtag
@@ -272,7 +273,12 @@ def del_master(realm, hostname, options):
         except Exception, e:
             sys.exit("There were issues removing a connection: %s" % e)
 
-    # 6. And clean up the removed replica DNS entries if any.
+    # 6. Pick CA renewal master
+    ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
+    if ca.is_renewal_master(hostname):
+        ca.set_renewal_master(options.host)
+
+    # 7. And clean up the removed replica DNS entries if any.
     try:
         if bindinstance.dns_container_exists(options.host, api.env.basedn,
                                              dm_password=options.dirman_passwd):
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index d468850..aa71095 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -28,7 +28,7 @@ import socket
 
 from ipapython import ipautil
 from ipaserver.install import replication, dsinstance, installutils
-from ipaserver.install import bindinstance
+from ipaserver.install import bindinstance, cainstance, certs
 from ipaserver.plugins import ldap2
 from ipapython import version, ipaldap
 from ipalib import api, errors, util
@@ -665,6 +665,7 @@ def del_master(realm, hostname, options):
         # Check that we are not leaving the installation without CA and/or DNS
         this_services = []
         other_services = []
+        ca_hostname = None
 
         for master_cn in [m.single_value['cn'] for m in masters]:
             master_dn = DN(('cn', master_cn), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), ipautil.realm_to_suffix(realm))
@@ -679,6 +680,8 @@ def del_master(realm, hostname, options):
                 this_services = services_cns
             else:
                 other_services.append(services_cns)
+                if ca_hostname is None and 'CA' in services_cns:
+                    ca_hostname = master_cn
 
         if 'CA' in this_services and not any(['CA' in o for o in other_services]):
             print "Deleting this server is not allowed as it would leave your installation without a CA."
@@ -688,6 +691,14 @@ def del_master(realm, hostname, options):
             print "Deleting this server will leave your installation without a DNS."
             if not options.force and not ipautil.user_input("Continue to delete?", False):
                 sys.exit("Deletion aborted")
+
+        # Pick CA renewal master
+        ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
+        if ca.is_renewal_master(hostname):
+            try:
+                ca.set_renewal_master(options.host)
+            except errors.NotFound:
+                ca.set_renewal_master(ca_hostname)
     else:
         print "Skipping calculation to determine if one or more masters would be orphaned."
 
-- 
1.9.3

>From 37d14195edff742a38ed46e598fb9bc942fb05e0 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 23 Jul 2014 19:03:46 +0200
Subject: [PATCH] Allow changing CA renewal master in ipa-csreplica-manage.

https://fedorahosted.org/freeipa/ticket/4039
---
 install/tools/ipa-csreplica-manage | 39 +++++++++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index cfcb354..c534446 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -34,15 +34,16 @@ from ipapython.dn import DN
 
 # dict of command name and tuples of min/max num of args needed
 commands = {
-    "list":(0, 1, "[master fqdn]", ""),
-    "connect":(1, 2, "<master fqdn> [other master fqdn]",
-                    "must provide the name of the servers to connect"),
-    "disconnect":(1, 2, "<master fqdn> [other master fqdn]",
-                    "must provide the name of the server to disconnect"),
-    "del":(1, 1, "<master fqdn>",
-                    "must provide hostname of master to delete"),
-    "re-initialize":(0, 0, "", ""),
-    "force-sync":(0, 0, "", "")
+    "list": (0, 1, "[master fqdn]", ""),
+    "connect": (1, 2, "<master fqdn> [other master fqdn]",
+                "must provide the name of the servers to connect"),
+    "disconnect": (1, 2, "<master fqdn> [other master fqdn]",
+                   "must provide the name of the server to disconnect"),
+    "del": (1, 1, "<master fqdn>",
+            "must provide hostname of master to delete"),
+    "re-initialize": (0, 0, "", ""),
+    "force-sync": (0, 0, "", ""),
+    "set-renewal-master": (0, 1, "[master fqdn]", "")
 }
 
 
@@ -375,6 +376,21 @@ def force_sync(realm, thishost, fromhost, dirman_passwd):
     except Exception, e:
         sys.exit(str(e))
 
+def set_renewal_master(realm, replica):
+    if not replica:
+        replica = installutils.get_fqdn()
+
+    ca = cainstance.CAInstance(realm, certs.NSS_DIR)
+    if ca.is_renewal_master(replica):
+        sys.exit("%s is already the renewal master" % replica)
+
+    try:
+        ca.set_renewal_master(replica)
+    except Exception, e:
+        sys.exit("Failed to set renewal master to %s: %s" % (replica, e))
+
+    print "%s is now the renewal master" % replica
+
 def main():
     options, args = parse_options()
 
@@ -439,6 +455,11 @@ def main():
             replica1 = host
             replica2 = args[1]
         del_link(realm, replica1, replica2, dirman_passwd, options.force)
+    elif args[0] == 'set-renewal-master':
+        replica = None
+        if len(args) > 1:
+            replica = args[1]
+        set_renewal_master(realm, replica)
 
 try:
     main()
-- 
1.9.3

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

Reply via email to