From d224655e4b1e218bac19dff5a10bf3e0d83edcb0 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Mon, 5 Jun 2017 12:41:02 +0000 Subject: [PATCH] pkinit manage: introduce ipa-pkinit-manage Add the ipa-pkinit-manage tool to allow enabling / disabling PKINIT after the initial server install. https://pagure.io/freeipa/issue/7000 Reviewed-By: Martin Babinsky --- freeipa.spec.in | 2 + install/tools/Makefile.am | 1 + install/tools/ipa-pkinit-manage | 8 +++ install/tools/man/Makefile.am | 1 + install/tools/man/ipa-pkinit-manage.1 | 34 +++++++++++++ ipaserver/install/ipa_pkinit_manage.py | 93 ++++++++++++++++++++++++++++++++++ ipaserver/install/krbinstance.py | 24 +++++++++ 7 files changed, 163 insertions(+) create mode 100755 install/tools/ipa-pkinit-manage create mode 100644 install/tools/man/ipa-pkinit-manage.1 create mode 100644 ipaserver/install/ipa_pkinit_manage.py diff --git a/freeipa.spec.in b/freeipa.spec.in index 2cbaa60df0db021a4a1ce10af383cd6a15e1e57c..ae77a9a23645c1490c32195203e2c4f665783a80 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -1184,6 +1184,7 @@ fi %{_sbindir}/ipa-advise %{_sbindir}/ipa-cacert-manage %{_sbindir}/ipa-winsync-migrate +%{_sbindir}/ipa-pkinit-manage %{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit %{_libexecdir}/certmonger/ipa-server-guard %dir %{_libexecdir}/ipa @@ -1247,6 +1248,7 @@ fi %{_mandir}/man1/ipa-otptoken-import.1* %{_mandir}/man1/ipa-cacert-manage.1* %{_mandir}/man1/ipa-winsync-migrate.1* +%{_mandir}/man1/ipa-pkinit-manage.1* %files -n python2-ipaserver diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am index 493e5ff4a8290be8ef076135104a85f8315b7842..47ecc14d7320336315c16587956c4965387853d9 100644 --- a/install/tools/Makefile.am +++ b/install/tools/Makefile.am @@ -28,6 +28,7 @@ dist_sbin_SCRIPTS = \ ipa-advise \ ipa-cacert-manage \ ipa-winsync-migrate \ + ipa-pkinit-manage \ $(NULL) appdir = $(libexecdir)/ipa/ diff --git a/install/tools/ipa-pkinit-manage b/install/tools/ipa-pkinit-manage new file mode 100755 index 0000000000000000000000000000000000000000..5b2413bd7cdc97632f82a77e18f3424a2ff63309 --- /dev/null +++ b/install/tools/ipa-pkinit-manage @@ -0,0 +1,8 @@ +#! /usr/bin/python2 -E +# +# Copyright (C) 2017 FreeIPA Contributors see COPYING for license +# + +from ipaserver.install.ipa_pkinit_manage import PKINITManage + +PKINITManage.run_cli() diff --git a/install/tools/man/Makefile.am b/install/tools/man/Makefile.am index 0d06ec7306b0cc1e656dac244bcb2c480b0ae61e..2dac9ac716352847aeb0d1fd3c6375ede956c751 100644 --- a/install/tools/man/Makefile.am +++ b/install/tools/man/Makefile.am @@ -27,6 +27,7 @@ dist_man1_MANS = \ ipa-otptoken-import.1 \ ipa-cacert-manage.1 \ ipa-winsync-migrate.1 \ + ipa-pkinit-manage.1 \ $(NULL) dist_man8_MANS = \ diff --git a/install/tools/man/ipa-pkinit-manage.1 b/install/tools/man/ipa-pkinit-manage.1 new file mode 100644 index 0000000000000000000000000000000000000000..5018ce8aa3f89470453d9cfc590a0c5f44f78f3c --- /dev/null +++ b/install/tools/man/ipa-pkinit-manage.1 @@ -0,0 +1,34 @@ +.\" +.\" Copyright (C) 2017 FreeIPA Contributors see COPYING for license +.\" +.TH "ipa-pkinit-manage" "1" "Jun 05 2017" "FreeIPA" "FreeIPA Manual Pages" +.SH "NAME" +ipa\-pkinit\-manage \- Enables or disables PKINIT +.SH "SYNOPSIS" +ipa\-pkinit\-manage [options] +.SH "DESCRIPTION" +Run the command with the \fBenable\fR option to enable PKINIT. + +Run the command with the \fBdisable\fR option to disable PKINIT. + +Run the command with the \fBstatus\fR to determine the current status of PKINIT. +.SH "OPTIONS" +.TP +\fB\-\-version\fR +Show the program's version and exit. +.TP +\fB\-h\fR, \fB\-\-help\fR +Show the help for this program. +.TP +\fB\-v\fR, \fB\-\-verbose\fR +Print debugging information. +.TP +\fB\-q\fR, \fB\-\-quiet\fR +Output only errors. +.TP +\fB\-\-log\-file\fR=\fIFILE\fR +Log to the given file. +.SH "EXIT STATUS" +0 if the command was successful + +1 if an error occurred diff --git a/ipaserver/install/ipa_pkinit_manage.py b/ipaserver/install/ipa_pkinit_manage.py new file mode 100644 index 0000000000000000000000000000000000000000..428c0e3476b4dbd13a9ee5a40a42447f9fa95f2d --- /dev/null +++ b/ipaserver/install/ipa_pkinit_manage.py @@ -0,0 +1,93 @@ +# +# Copyright (C) 2017 FreeIPA Contributors see COPYING for license +# + +from __future__ import print_function + +from ipalib import api +from ipaplatform.paths import paths +from ipapython.admintool import AdminTool +from ipaserver.install.krbinstance import KrbInstance, is_pkinit_enabled + + +class PKINITManage(AdminTool): + command_name = "ipa-pkinit-manage" + usage = "%prog " + description = "Manage PKINIT." + + def validate_options(self): + super(PKINITManage, self).validate_options(needs_root=True) + + option_parser = self.option_parser + + if not self.args: + option_parser.error("action not specified") + elif len(self.args) > 1: + option_parser.error("too many arguments") + + action = self.args[0] + if action not in {'enable', 'disable', 'status'}: + option_parser.error("unrecognized action '{}'".format(action)) + + def run(self): + api.bootstrap(in_server=True, confdir=paths.ETC_IPA) + api.finalize() + + api.Backend.ldap2.connect() + try: + action = self.args[0] + if action == 'enable': + self.enable() + elif action == 'disable': + self.disable() + elif action == 'status': + self.status() + finally: + api.Backend.ldap2.disconnect() + + return 0 + + def _setup(self, setup_pkinit): + config = api.Command.config_show()['result'] + ca_enabled = api.Command.ca_is_enabled()['result'] + + krb = KrbInstance() + krb.init_info( + realm_name=api.env.realm, + host_name=api.env.host, + setup_pkinit=setup_pkinit, + subject_base=config['ipacertificatesubjectbase'][0], + ) + + if bool(is_pkinit_enabled()) is not bool(setup_pkinit): + try: + krb.stop_tracking_certs() + except RuntimeError as e: + if ca_enabled: + self.log.warning( + "Failed to stop tracking certificates: %s", e) + + krb.enable_ssl() + + if setup_pkinit: + krb.pkinit_enable() + else: + krb.pkinit_disable() + + def enable(self): + if not api.Command.ca_is_enabled()['result']: + self.log.error("Cannot enable PKINIT in CA-less deployment") + self.log.error("Use ipa-server-certinstall to install KDC " + "certificate manually") + raise RuntimeError("Cannot enable PKINIT in CA-less deployment") + + self._setup(True) + + def disable(self): + self._setup(False) + + def status(self): + if is_pkinit_enabled(): + print("PKINIT is enabled") + else: + print("PKINIT is disabled") diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index a1053d55ccaae17bef93547c036fb9d08d296f0b..6b51e65d1ec985bfc01f167aea3fe3ca11c7ec29 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -451,6 +451,30 @@ class KrbInstance(service.Service): service.set_service_entry_config( 'KDC', self.fqdn, [PKINIT_ENABLED], self.suffix) + def pkinit_disable(self): + """ + unadvertise enabled PKINIT feature in master's KDC entry in LDAP + """ + ldap = api.Backend.ldap2 + dn = DN(('cn', 'KDC'), + ('cn', self.fqdn), + ('cn', 'masters'), + ('cn', 'ipa'), + ('cn', 'etc'), + self.suffix) + + entry = ldap.get_entry(dn, ['ipaConfigString']) + + config = entry.setdefault('ipaConfigString', []) + config = [value for value in config + if value.lower() != PKINIT_ENABLED.lower()] + entry['ipaConfigString'][:] = config + + try: + ldap.update_entry(entry) + except errors.EmptyModlist: + pass + def _install_pkinit_ca_bundle(self): ca_certs = certstore.get_ca_certs(self.api.Backend.ldap2, self.api.env.basedn, -- 2.9.4