X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Fhelpers%2Fipa.py;h=2caddb3bc720f05aeb5117445bc72babc791acb0;hp=df6717f0a5b93eecdebe5e0db63174af7ec03b9a;hb=bf5398120e33ff3e88d7b3794c9437e7e75ee369;hpb=33d8af8c15d28a32c42f056546cf391b2cffa803 diff --git a/ipsilon/helpers/ipa.py b/ipsilon/helpers/ipa.py old mode 100755 new mode 100644 index df6717f..2caddb3 --- a/ipsilon/helpers/ipa.py +++ b/ipsilon/helpers/ipa.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# # Copyright (C) 2014 Simo Sorce # # see file 'COPYING' for use and warranty information @@ -24,6 +22,8 @@ import socket import subprocess import sys +from ipsilon.helpers.common import EnvHelpersInstaller + IPA_CONFIG_FILE = '/etc/ipa/default.conf' HTTPD_IPA_KEYTAB = '/etc/httpd/conf/ipa.keytab' @@ -44,9 +44,10 @@ failure (see logs) and retry. """ -class Installer(object): +class Installer(EnvHelpersInstaller): - def __init__(self): + def __init__(self, *pargs): + super(Installer, self).__init__() self.name = 'ipa' self.ptype = 'helper' self.logger = None @@ -78,7 +79,7 @@ class Installer(object): self.server = ipaconfig.config.get_server() except Exception, e: # pylint: disable=broad-except - logger.info('IPA tools installation found: [%s]', str(e)) + logger.info('IPA tools installation found: [%s]', e) if opts['ipa'] == 'yes': raise Exception('No IPA installation found!') return @@ -93,47 +94,81 @@ class Installer(object): # Check if we already have a keytab for HTTP if 'krb_httpd_keytab' in opts: + msg = "Searching for keytab in: %s" % opts['krb_httpd_keytab'] + print >> sys.stdout, msg, if os.path.exists(opts['krb_httpd_keytab']): + print >> sys.stdout, "... Found!" return + else: + print >> sys.stdout, "... Not found!" + msg = "Searching for keytab in: %s" % HTTPD_IPA_KEYTAB + print >> sys.stdout, msg, if os.path.exists(HTTPD_IPA_KEYTAB): opts['krb_httpd_keytab'] = HTTPD_IPA_KEYTAB + print >> sys.stdout, "... Found!" return + else: + print >> sys.stdout, "... Not found!" us = socket.gethostname() princ = 'HTTP/%s@%s' % (us, self.realm) # Check we have credentials to access server (for keytab) - from ipapython import ipaldap + from ipalib import api from ipalib import errors as ipaerrors - for srv in self.server: - try: - server = srv - c = ipaldap.IPAdmin(host=server) - c.do_sasl_gssapi_bind() - del c - break - except ipaerrors.ACIError, e: - # usually this error is returned when we have no - # good credentials, ask the user to kinit and retry - print >> sys.stderr, NO_CREDS_FOR_KEYTAB - logger.error('Invalid credentials: [%s]', repr(e)) - raise Exception('Invalid credentials: [%s]', str(e)) - except Exception, e: # pylint: disable=broad-except - # for other exceptions let's try to fail later - pass + api.bootstrap(context='ipsilon_installer') + api.finalize() try: - subprocess.check_output([IPA_COMMAND, 'service-add', princ], - stderr=subprocess.STDOUT) - except subprocess.CalledProcessError, e: - # hopefully this means the service already exists - # otherwise we'll fail later again - logger.info('Error trying to create HTTP service:') - logger.info('Cmd> %s\n%s', e.cmd, e.output) + api.Backend.rpcclient.connect() + logger.debug('Try RPC connection') + api.Backend.rpcclient.forward('ping') + print >> sys.stdout, "... Succeeded!" + except ipaerrors.KerberosError as e: + print >> sys.stderr, NO_CREDS_FOR_KEYTAB + logger.error('Invalid credentials: [%s]', repr(e)) + if api.Backend.rpcclient.isconnected(): + api.Backend.rpcclient.disconnect() + raise Exception('Invalid credentials: [%s]' % e) + except ipaerrors.PublicError as e: + print >> sys.stderr, "Can't connect to any IPA server" + logger.error( + 'Cannot connect to the server due to generic error: %s', e) + if api.Backend.rpcclient.isconnected(): + api.Backend.rpcclient.disconnect() + raise Exception('Unable to connect to IPA server: %s' % e) + + # Specify an older version to work on nearly any master. Force is + # set to True so a DNS A record is not required for adding the + # service. + try: + api.Backend.rpcclient.forward( + 'service_add', + unicode(princ), + force=True, + version=u'2.0', + ) + except ipaerrors.DuplicateEntry: + logger.debug('Principal %s already exists', princ) + except ipaerrors.NotFound as e: + print >> sys.stderr, "%s" % e + logger.error('%s', e) + raise Exception('%s' % e) + except ipaerrors.ACIError as e: + print >> sys.stderr, NO_CREDS_FOR_KEYTAB + logger.error('Invalid credentials: [%s]', repr(e)) + raise Exception('Invalid credentials: [%s]' % e) + finally: + server = api.Backend.rpcclient.api.env.server + if api.Backend.rpcclient.isconnected(): + api.Backend.rpcclient.disconnect() try: + msg = "Trying to fetch keytab[%s] for %s" % ( + opts['krb_httpd_keytab'], princ) + print >> sys.stdout, msg, subprocess.check_output([IPA_GETKEYTAB, '-s', server, '-p', princ, '-k', opts['krb_httpd_keytab']], @@ -143,7 +178,7 @@ class Installer(object): print >> sys.stderr, FAILED_TO_GET_KEYTAB logger.info('Error trying to get HTTP keytab:') logger.info('Cmd> %s\n%s', e.cmd, e.output) - raise Exception('Missing keytab: [%s]' % str(e)) + raise Exception('Missing keytab: [%s]' % e) # Fixup permissions so only the ipsilon user can read these files pw = pwd.getpwnam(HTTPD_USER) @@ -152,6 +187,8 @@ class Installer(object): def configure_server(self, opts): if opts['ipa'] != 'yes' and opts['ipa'] != 'auto': return + if opts['ipa'] != 'yes' and opts['krb'] == 'no': + return self.logger = logging.getLogger() @@ -160,11 +197,11 @@ class Installer(object): self.get_keytab(opts) # Forcibly use krb then pam modules - if not 'lm_order' in opts: + if 'lm_order' not in opts: opts['lm_order'] = [] opts['krb'] = 'yes' if 'krb' not in opts['lm_order']: opts['lm_order'].insert(0, 'krb') - opts['pam'] = 'yes' - if 'pam' not in opts['lm_order']: - opts['lm_order'].append('pam') + opts['form'] = 'yes' + if not any(lm in opts['lm_order'] for lm in ('form', 'pam')): + opts['lm_order'].append('form')