On 10/22/2015 05:32 PM, Petr Spacek wrote:
On 21.10.2015 17:55, Martin Babinsky wrote:
On 10/13/2015 09:17 AM, Petr Spacek wrote:
On 12.10.2015 13:38, Martin Babinsky wrote:

each service possessing Kerberos keytab wiil now remove it and destroy any
associated credentials cache during its uninstall

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

BTW some time ago Simo proposed that we should remove caches and old keytabs
during *install* so problems caused by failing uninstallation will be fixed on
repeated install. This is yet another step towards idempotent installer.

To me this makes more sense than doing so on uninstall. Does it make sense to
you, too?


Attaching updated patch that does cleanup also before each instance creation.
It is a bit ugly I admit, but I couldn't think of a better way to do it and
didn't want to poke into service/instance code more than neccesary.

NACK, but we are almost there!

* kdestroy -A is too aggressive and wipes root's keyring after each run of
ipa-*-install utils.

* There are some scattered leftovers of ipautil.run['kdestroy'...] in the
tree. Please get rid of them.

Thank you!

Attaching updated patch. It got lost somewhere in the list.

--
Martin^3 Babinsky
From a6bc5bc86bcf319f26e2103b6d258ec8eb6d2d0c Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Fri, 9 Oct 2015 18:08:38 +0200
Subject: [PATCH] remove Kerberos authenticators when installing/uninstalling
 service instance

each service possessing Kerberos keytab/ccache will now perform their removal
before service principal creation and during service uninstall

https://fedorahosted.org/freeipa/ticket/5243
---
 ipaserver/install/adtrustinstance.py     |  4 ++--
 ipaserver/install/bindinstance.py        |  3 +++
 ipaserver/install/dnskeysyncinstance.py  |  3 +++
 ipaserver/install/dsinstance.py          |  4 ++--
 ipaserver/install/httpinstance.py        | 11 ++++++----
 ipaserver/install/installutils.py        | 37 ++++++++++++++++++++++++++++++++
 ipaserver/install/odsexporterinstance.py |  3 +++
 7 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index f7a7899906ca47b4901881fb6f4099ace1780741..6c083358081de7f5a47cf25f5d13469b2217978a 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -528,6 +528,7 @@ class ADTRUSTInstance(service.Service):
             self.print_msg("Cannot add CIFS service: %s" % e)
 
         self.clean_samba_keytab()
+        installutils.remove_ccache(paths.KRB5CC_SAMBA)
 
         try:
             ipautil.run(["ipa-getkeytab", "--server", self.fqdn,
@@ -918,8 +919,7 @@ class ADTRUSTInstance(service.Service):
             self.print_msg('WARNING: ' + str(e))
 
         # Remove samba's credentials cache
-        krb5cc_samba = paths.KRB5CC_SAMBA
-        installutils.remove_file(krb5cc_samba)
+        installutils.remove_ccache(ccache_path=paths.KRB5CC_SAMBA)
 
         # Remove samba's configuration file
         installutils.remove_file(self.smb_conf)
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 0bc0557cc10a6d32f71cc0426ce350c394216022..51c5d2df4e16b85c68698da45a1c4ce7b10c771d 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -1202,3 +1202,6 @@ class BindInstance(service.Service):
 
         if named_regular_running:
             self.named_regular.start()
+
+        installutils.remove_keytab(paths.NAMED_KEYTAB)
+        installutils.remove_ccache(run_as='named')
diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py
index 68130c92558a4feb8d08fa826dbf6333d4461d1f..b2ccc027469a352c815963abfd0c0a61dd37297f 100644
--- a/ipaserver/install/dnskeysyncinstance.py
+++ b/ipaserver/install/dnskeysyncinstance.py
@@ -417,6 +417,7 @@ class DNSKeySyncInstance(service.Service):
 
     def __setup_principal(self):
         assert self.ods_gid is not None
+        installutils.remove_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB)
         dnssynckey_principal = "ipa-dnskeysyncd/" + self.fqdn + "@" + self.realm
         installutils.kadmin_addprinc(dnssynckey_principal)
 
@@ -497,3 +498,5 @@ class DNSKeySyncInstance(service.Service):
             os.remove(paths.DNSSEC_SOFTHSM_PIN)
         except Exception:
             pass
+
+        installutils.remove_keytab(paths.IPA_DNSKEYSYNCD_KEYTAB)
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 15b23a8704091fbcf54e5be52562f6da2eeb1d73..7bdcaea31dcdf593d1de3b98a2ddfb926c2ea990 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -937,8 +937,8 @@ class DsInstance(service.Service):
             root_logger.debug("Removing DS instance %s" % serverid)
             try:
                 remove_ds_instance(serverid)
-                root_logger.debug("Removing DS keytab")
-                installutils.remove_file(paths.DS_KEYTAB)
+                installutils.remove_keytab(paths.DS_KEYTAB)
+                installutils.remove_ccache(run_as=DS_USER)
             except ipautil.CalledProcessError:
                 root_logger.error("Failed to remove DS instance. You may "
                                   "need to remove instance data manually")
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 0d1074dbda486f6102dd1628d720080e6dfb7ff7..7ae39463f5c59d3ec285fa3757cf629fd8f209f9 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -186,6 +186,7 @@ class HTTPInstance(service.Service):
 
     def __create_http_keytab(self):
         if not self.promote:
+            installutils.remove_keytab(paths.IPA_KEYTAB)
             installutils.kadmin_addprinc(self.principal)
             installutils.create_keytab(paths.IPA_KEYTAB, self.principal)
             self.move_service(self.principal)
@@ -197,7 +198,8 @@ class HTTPInstance(service.Service):
         # Clean up existing ccache
         # Make sure that empty env is passed to avoid passing KRB5CCNAME from
         # current env
-        ipautil.run(['kdestroy', '-A'], runas='apache', raiseonerr=False, env={})
+        ipautil.run(
+            [paths.KDESTROY, '-A'], runas='apache', raiseonerr=False, env={})
 
     def __configure_http(self):
         target_fname = paths.HTTPD_IPA_CONF
@@ -496,9 +498,10 @@ class HTTPInstance(service.Service):
                 root_logger.debug(error)
                 pass
 
-        # Remove the ccache file for the HTTPD service
-        ipautil.run([paths.KDESTROY, '-c', paths.KRB5CC_HTTPD], runas='apache',
-                    raiseonerr=False)
+        # Remove HTTPD service keytab and credentials cache
+        installutils.remove_keytab(paths.IPA_KEYTAB)
+        installutils.remove_ccache(ccache_path=paths.KRB5CC_HTTPD,
+                                   run_as='apache')
 
         # Remove the configuration files we create
         installutils.remove_file(paths.HTTPD_IPA_REWRITE_CONF)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 1d3551f8bb9cfcac1f6fa24043aea4b5d0a07719..71bdafa44a23eaaf964b3d00e855fb52c2acb18f 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -20,6 +20,7 @@
 from __future__ import absolute_import
 from __future__ import print_function
 
+import errno
 import socket
 import getpass
 import gssapi
@@ -1353,3 +1354,39 @@ class ModifyLDIF(ldif.LDIFParser):
         for dn in remaining_changes:
             root_logger.error(
                 "DN: %s does not exists or haven't been updated", dn)
+
+
+def remove_keytab(keytab_path):
+    """
+    Remove Kerberos keytab and issue a warning if the procedure fails
+
+    :param keytab_path: path to the keytab file
+    """
+    try:
+        root_logger.debug("Removing service keytab: {}".format(keytab_path))
+        os.remove(keytab_path)
+    except OSError as e:
+        if e.errno != errno.ENOENT:
+            root_logger.warning("Failed to remove Kerberos keytab '{}': "
+                                "{}".format(keytab_path, e))
+            root_logger.warning("You may have to remove it manually")
+
+
+def remove_ccache(ccache_path=None, run_as=None):
+    """
+    remove Kerberos credential cache, essentially a wrapper around kdestroy.
+
+    :param ccache_path: path to the ccache file
+    :param run_as: run kdestroy as this user
+    """
+    root_logger.debug("Removing service credentials cache")
+    kdestroy_cmd = [paths.KDESTROY]
+    if ccache_path is not None:
+        root_logger.debug("Ccache path: '{}'".format(ccache_path))
+        kdestroy_cmd.extend(['-c', ccache_path])
+
+    try:
+        ipautil.run(kdestroy_cmd, runas=run_as, env={})
+    except ipautil.CalledProcessError as e:
+        root_logger.warning(
+            "Failed to clear Kerberos credentials cache: {}".format(e))
diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py
index 85c64aba4d7b2fb1b5f1f5c6345521458a8388f5..deab4ea629d8faefd03c9b4d740ef4a24bc903ce 100644
--- a/ipaserver/install/odsexporterinstance.py
+++ b/ipaserver/install/odsexporterinstance.py
@@ -193,3 +193,6 @@ class ODSExporterInstance(service.Service):
 
         if signerd_running:
             signerd_service.start()
+
+        installutils.remove_keytab(paths.IPA_ODS_EXPORTER_KEYTAB)
+        installutils.remove_ccache(ccache_path=paths.IPA_ODS_EXPORTER_CCACHE)
-- 
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