summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/fedora/ipsilon.spec1
-rwxr-xr-xipsilon/helpers/ipa.py170
-rwxr-xr-xsetup.py2
3 files changed, 172 insertions, 1 deletions
diff --git a/contrib/fedora/ipsilon.spec b/contrib/fedora/ipsilon.spec
index f86e4de..f5e1931 100644
--- a/contrib/fedora/ipsilon.spec
+++ b/contrib/fedora/ipsilon.spec
@@ -98,6 +98,7 @@ semanage fcontext -d -t httpd_var_lib_t '%{_sharedstatedir}/ipsilon(/.*)?' 2>/de
%{python2_sitelib}/ipsilon-*.egg-info
%{python2_sitelib}/ipsilon/__init__.py*
%{python2_sitelib}/ipsilon/tools/*
+%{python2_sitelib}/ipsilon/helpers/*
%{_datadir}/ipsilon/templates/install/saml2/sp.conf
%{_datadir}/ipsilon/ui/saml2sp/*
%{_bindir}/ipsilon-client-install
diff --git a/ipsilon/helpers/ipa.py b/ipsilon/helpers/ipa.py
new file mode 100755
index 0000000..df6717f
--- /dev/null
+++ b/ipsilon/helpers/ipa.py
@@ -0,0 +1,170 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2014 Simo Sorce <simo@redhat.com>
+#
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+import pwd
+import os
+import socket
+import subprocess
+import sys
+
+
+IPA_CONFIG_FILE = '/etc/ipa/default.conf'
+HTTPD_IPA_KEYTAB = '/etc/httpd/conf/ipa.keytab'
+IPA_COMMAND = '/usr/bin/ipa'
+IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+HTTPD_USER = 'apache'
+
+NO_CREDS_FOR_KEYTAB = """
+Valid IPA admin credentials are required to get a keytab.
+Please kinit with a pivileged user like 'admin' and retry.
+"""
+
+FAILED_TO_GET_KEYTAB = """
+A pre-existing keytab was not found and it was not possible to
+successfully retrieve a new keytab for the IPA server. Please
+manually provide a keytab or resolve the error that cause this
+failure (see logs) and retry.
+"""
+
+
+class Installer(object):
+
+ def __init__(self):
+ self.name = 'ipa'
+ self.ptype = 'helper'
+ self.logger = None
+ self.realm = None
+ self.domain = None
+ self.server = None
+
+ def install_args(self, group):
+ group.add_argument('--ipa', choices=['yes', 'no', 'auto'],
+ default='auto',
+ help='Helper for IPA joined machines')
+
+ def conf_init(self, opts):
+ logger = self.logger
+ # Do a simple check to see if machine is ipa joined
+ if not os.path.exists(IPA_CONFIG_FILE):
+ logger.info('No IPA configuration file. Skipping ipa helper...')
+ if opts['ipa'] == 'yes':
+ raise Exception('No IPA installation found!')
+ return
+
+ # Get config vars from ipa file
+ try:
+ from ipapython import config as ipaconfig
+
+ ipaconfig.init_config()
+ self.realm = ipaconfig.config.get_realm()
+ self.domain = ipaconfig.config.get_domain()
+ self.server = ipaconfig.config.get_server()
+
+ except Exception, e: # pylint: disable=broad-except
+ logger.info('IPA tools installation found: [%s]', str(e))
+ if opts['ipa'] == 'yes':
+ raise Exception('No IPA installation found!')
+ return
+
+ def get_keytab(self, opts):
+ logger = self.logger
+ # Check if we have need ipa tools
+ if not os.path.exists(IPA_GETKEYTAB):
+ logger.info('ipa-getkeytab missing. Will skip keytab creation.')
+ if opts['ipa'] == 'yes':
+ raise Exception('No IPA tools found!')
+
+ # Check if we already have a keytab for HTTP
+ if 'krb_httpd_keytab' in opts:
+ if os.path.exists(opts['krb_httpd_keytab']):
+ return
+
+ if os.path.exists(HTTPD_IPA_KEYTAB):
+ opts['krb_httpd_keytab'] = HTTPD_IPA_KEYTAB
+ return
+
+ 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 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
+
+ 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)
+
+ try:
+ subprocess.check_output([IPA_GETKEYTAB,
+ '-s', server, '-p', princ,
+ '-k', opts['krb_httpd_keytab']],
+ stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError, e:
+ # unfortunately this one is fatal
+ 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))
+
+ # Fixup permissions so only the ipsilon user can read these files
+ pw = pwd.getpwnam(HTTPD_USER)
+ os.chown(opts['krb_httpd_keytab'], pw.pw_uid, pw.pw_gid)
+
+ def configure_server(self, opts):
+ if opts['ipa'] != 'yes' and opts['ipa'] != 'auto':
+ return
+
+ self.logger = logging.getLogger()
+
+ self.conf_init(opts)
+
+ self.get_keytab(opts)
+
+ # Forcibly use krb then pam modules
+ if not 'lm_order' 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')
diff --git a/setup.py b/setup.py
index 4b4406b..4bf2a41 100755
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,7 @@ setup(
license = 'GPLv3+',
packages = ['ipsilon', 'ipsilon.admin', 'ipsilon.login', 'ipsilon.util',
'ipsilon.providers', 'ipsilon.providers.saml2',
- 'ipsilon.tools'],
+ 'ipsilon.tools', 'ipsilon.helpers'],
data_files = [('share/man/man7', ["man/ipsilon.7"]),
('share/doc/ipsilon', ['COPYING']),
('share/doc/ipsilon/examples', ['examples/ipsilon.conf',