On 01/15/2016 04:57 PM, Simo Sorce wrote:
On Fri, 2016-01-15 at 13:35 +0100, Martin Babinsky wrote:
On 01/14/2016 10:31 PM, Simo Sorce wrote:
On Wed, 2016-01-13 at 17:31 +0100, Martin Babinsky wrote:
On 01/13/2016 10:31 AM, Martin Babinsky wrote:
On 01/07/2016 05:38 PM, Martin Babinsky wrote:
On 01/07/2016 05:37 PM, Martin Babinsky wrote:

And the patch is here.

self-NACK, there may be a better way to handle this. I will do some
investigation and send updated patch.

Attaching updated patch.

A failure to obtain a tgt may be due to other reasons (for example the
KDC crashed), why are you trying to use this test ?
Isn't it sufficient to see there is no host entry in the directory ?


There were some corner cases I encountered, mostly concerning a cleanup
after unsuccessful replica promotion.

You may sometimes end up in a state where local DS is working, but KDC
crashed and the krb5.conf is still pointing at a remote one. In that
case "malformed" replica's local host entry exist, but when such host
tries to get TGT, the AS-REQ goes to remote KDC from other master.

However, if the admin had in the mean time cleaned up this host's
kerberos principals/keys, the crashed replica gets one of the following

Client not found in Kerberos database
Client credentials have been revoked
Generic preauthentication failure

These were printed out as errors during uninstall, but were actually
expected in situation like this. It is true that the code should check
and ignore these specific errors.

Only the first id valid for your case, the others may be transient


True, attaching updated patch. The other errors will now pop out in the output and the warning will be displayed.

Martin^3 Babinsky
From 6517633c8b8019ad275e85c2273177a1275bdc62 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Thu, 7 Jan 2016 16:48:11 +0100
Subject: [PATCH] uninstallation: more robust check for master removal from

When uninstalling IPA master in domain level 1 topology, the code that checks
for correct removal from topology will now consider failures to lookup host
entry in local LDAP and to obtain host TGT as a sign that the master entry was
already removed.

 ipalib/krb_utils.py                 |  1 +
 ipaserver/install/server/install.py | 40 +++++++++++++++++++++++++++++++++----
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/ipalib/krb_utils.py b/ipalib/krb_utils.py
index 0c4340c3f232135b64dafb6a675ffbcdd7ea59cd..b33e4b7c82cf08c68220531ebacca309117ad770 100644
--- a/ipalib/krb_utils.py
+++ b/ipalib/krb_utils.py
@@ -32,6 +32,7 @@ if six.PY3:
 # Kerberos error codes
 KRB5_CC_NOTFOUND                = 2529639053 # Matching credential not found
 KRB5_FCC_NOFILE                 = 2529639107 # No credentials cache found
+KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN = 2529638918  # client not found in Kerberos db
 KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN = 2529638919 # Server not found in Kerberos database
 KRB5KRB_AP_ERR_TKT_EXPIRED      = 2529638944 # Ticket expired
 KRB5_FCC_PERM                   = 2529639106 # Credentials cache permissions incorrect
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 49e97eb667a322898acc3a064f4eae5381ded918..362b99f320a7e83ff0427924c41f3e26a42c3226 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -4,6 +4,7 @@
 from __future__ import print_function
+import gssapi
 import os
 import pickle
 import pwd
@@ -27,6 +28,7 @@ from ipaplatform import services
 from ipaplatform.paths import paths
 from ipaplatform.tasks import tasks
 from ipalib import api, create_api, constants, errors, x509
+from ipalib.krb_utils import KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
 from ipalib.constants import CACERT
 from ipalib.util import validate_domain_name
 import ipaclient.ntpconf
@@ -291,20 +293,50 @@ def common_cleanup(func):
 def check_master_deleted(api, masters, interactive):
+    """
+    Determine whether the IPA master was removed from the domain level 1
+    topology. The function first tries to locally lookup the master host entry
+    and fetches host prinicipal from DS. Then we attempt to acquire host TGT,
+    contact the other masters one at a time and query for the existence of the
+    host entry for our IPA master.
+    :param api: instance of API object
+    :param masters: list of masters to contact
+    :param interactive: whether run in interactive mode. The user will be
+        prompted for action if the removal status cannot be determined
+    :return: True if the master is not part of the topology anymore as
+        determined by the following conditions:
+            * the host entry does not exist in local DS
+            * request for host TGT fails due to missing/invalid/revoked creds
+            * GSSAPI connection to remote DS fails on invalid authentication
+            * if we are the only master
+        False otherwise
+    """
         host_princ = api.Command.host_show(
-    except Exception as e:
-        root_logger.warning(
-            "Failed to get host principal name: {0}".format(e)
+    except errors.NotFound:
+        root_logger.debug(
+            "Host entry for {} already deleted".format(api.env.host)
+        return True
+    except Exception as e:
+        root_logger.warning("Failed to get host principal name: {0}".format(e))
         return False
     ccache_path = os.path.join('/', 'tmp', 'krb5cc_host')
     with ipautil.private_ccache(ccache_path):
+        # attempt to get host TGT. This can fail if the master contacts remote
+        # KDCs on other masters that have already cleared our master's
+        # principal. In that case return True
             ipautil.kinit_keytab(host_princ, paths.KRB5_KEYTAB, ccache_path)
-        except Exception as e:
+        except gssapi.exceptions.GSSError as e:
+            if e.min_code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
+                root_logger.debug("Host principal not found, assuming that "
+                                  "master is removed from topology")
+                return True
                 "Kerberos authentication as '{0}' failed: {1}".format(
                     host_princ, e

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

Reply via email to