Add compatibility for IPA 4.4 which requires TGT for API

IPA 4.4 added thin client capabilities. This is done by downloading
the call schema from the IPA server and is done during the
finalize() step. This requires a TGT.

So we need to ensure that a kinit is done before finalize() is
called both in the standalone installer and in the ipa code.

Change-Id: Id87b83cb945c946cf78c425aae19c311d900249a
This commit is contained in:
Rob Crittenden 2017-01-18 14:41:47 -05:00
parent b67243c163
commit 8078c6161f
3 changed files with 30 additions and 7 deletions

View File

@ -156,7 +156,7 @@ class NovajoinRole(object):
return nss_db
def kinit(self, principal, password, config=None):
def kinit(self, principal, realm, password, config=None):
ccache_dir = tempfile.mkdtemp(prefix='krbcc')
self.ccache_name = os.path.join(ccache_dir, 'ccache')
@ -165,7 +165,7 @@ class NovajoinRole(object):
if principal.find('@') == -1:
# pylint: disable=no-member
principal = '%s@%s' % (principal, api.env.realm)
principal = '%s@%s' % (principal, realm)
try:
kinit_password(principal, password, self.ccache_name,

View File

@ -28,6 +28,7 @@ except ImportError:
from novajoin.util import get_domain
from oslo_config import cfg
from oslo_log import log as logging
from six.moves.configparser import SafeConfigParser
CONF = cfg.CONF
@ -47,10 +48,31 @@ class IPANovaJoinBase(object):
self.ccache = "MEMORY:" + str(uuid.uuid4())
os.environ['KRB5CCNAME'] = self.ccache
if self._ipa_client_configured() and not api.isdone('finalize'):
(hostname, realm) = self.__get_host_and_realm()
kinit_keytab(str('nova/%s@%s' % (hostname, realm)),
CONF.keytab, self.ccache)
api.bootstrap(context='novajoin')
api.finalize()
self.batch_args = list()
def __get_host_and_realm(self):
"""Return the hostname and IPA realm name.
IPA 4.4 introduced the requirement that the schema be
fetched when calling finalize(). This is really only used by
the ipa command-line tool but for now it is baked in.
So we have to get a TGT first but need the hostname and
realm. For now directly read the IPA config file which is
in INI format and pull those two values out and return as
a tuple.
"""
config = SafeConfigParser()
config.read('/etc/ipa/default.conf')
hostname = config.get('global', 'host')
realm = config.get('global', 'realm')
return (hostname, realm)
def __get_connection(self):
"""Make a connection to IPA or raise an error."""
tries = 0

View File

@ -65,9 +65,6 @@ if __name__ == '__main__':
precreate_opts_specified = (opts.precreate and opts.domain
and opts.realm and opts.server)
api.bootstrap(**args)
api.finalize()
# suppress the Forwarding messages from ipa
console = log_mgr.get_handler('console')
console.setLevel(logging.WARN)
@ -79,11 +76,12 @@ if __name__ == '__main__':
if not opts.no_kinit:
if precreate_opts_specified:
krb5_conf = novajoin.create_krb5_conf(opts)
os.environ['KRB5_CONFIG'] = krb5_conf
else:
krb5_conf = None
try:
ccache_dir = novajoin.kinit(opts.principal, opts.password,
krb5_conf)
ccache_dir = novajoin.kinit(opts.principal, opts.realm,
opts.password, krb5_conf)
except ConfigurationError:
if krb5_conf:
os.remove(krb5_conf)
@ -92,6 +90,9 @@ if __name__ == '__main__':
if precreate_opts_specified:
nss_db = novajoin.create_nssdb(opts.server, opts.realm)
args['nss_dir'] = unicode(nss_db.secdir)
api.bootstrap(**args)
api.finalize()
logging.debug('Connect to IPA backend')
try: