summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Babinsky <mbabinsk@redhat.com>2016-01-07 16:48:11 +0100
committerMartin Basti <mbasti@redhat.com>2016-01-21 18:12:42 +0100
commitd726da3ba20283ffdc1d384dfedf8e6a732dc3d7 (patch)
treeebac189c1abeb0af3b8642606e3f69d07c3470fa
parentfd7ea2c9395651d5bce41cc603557fea107f65a7 (diff)
downloadfreeipa-d726da3ba20283ffdc1d384dfedf8e6a732dc3d7.tar.gz
freeipa-d726da3ba20283ffdc1d384dfedf8e6a732dc3d7.tar.xz
freeipa-d726da3ba20283ffdc1d384dfedf8e6a732dc3d7.zip
uninstallation: more robust check for master removal from topology
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. https://fedorahosted.org/freeipa/ticket/5584 Reviewed-By: Simo Sorce <ssorce@redhat.com> Reviewed-By: Martin Basti <mbasti@redhat.com>
-rw-r--r--ipalib/krb_utils.py1
-rw-r--r--ipaserver/install/server/install.py40
2 files changed, 37 insertions, 4 deletions
diff --git a/ipalib/krb_utils.py b/ipalib/krb_utils.py
index 0c4340c3f..b33e4b7c8 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 49e97eb66..362b99f32 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
+ """
try:
host_princ = api.Command.host_show(
api.env.host)['result']['krbprincipalname'][0]
- 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
try:
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
+
root_logger.error(
"Kerberos authentication as '{0}' failed: {1}".format(
host_princ, e