URL: https://github.com/freeipa/freeipa/pull/852 Author: HonzaCholasta Title: #852: pkinit manage: introduce ipa-pkinit-manage Action: opened
PR body: """ **server certinstall: update KDC master entry** After the KDC certificate is installed, add the PKINIT enabled flag to the KDC master entry. **pkinit manage: introduce ipa-pkinit-manage** Add the ipa-pkinit-manage tool to allow enabling / disabling PKINIT after the initial server install. **server upgrade: do not enable PKINIT by default** Enabling PKINIT often fails during server upgrade when requesting the KDC certificate. Now that PKINIT can be enabled post-install using ipa-pkinit-manage, avoid the upgrade failure by not enabling PKINIT by default. https://pagure.io/freeipa/issue/7000 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/852/head:pr852 git checkout pr852
From 7b0c3bc294a3437a05a69f67d7f88ddc89ec913d Mon Sep 17 00:00:00 2001 From: Jan Cholasta <jchol...@redhat.com> Date: Mon, 5 Jun 2017 12:35:52 +0000 Subject: [PATCH 1/3] server certinstall: update KDC master entry After the KDC certificate is installed, add the PKINIT enabled flag to the KDC master entry. https://pagure.io/freeipa/issue/7000 --- ipaserver/install/ipa_server_certinstall.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index a14a84f188..9c8f6e81a8 100644 --- a/ipaserver/install/ipa_server_certinstall.py +++ b/ipaserver/install/ipa_server_certinstall.py @@ -34,7 +34,7 @@ verify_kdc_cert_validity) from ipapython.dn import DN from ipalib import api, errors -from ipaserver.install import certs, dsinstance, installutils +from ipaserver.install import certs, dsinstance, installutils, krbinstance class ServerCertInstall(admintool.AdminTool): @@ -223,6 +223,13 @@ def install_kdc_cert(self): except RuntimeError as e: raise admintool.ScriptError(str(e)) + krb = krbinstance.KrbInstance() + krb.init_info( + realm_name=api.env.realm, + host_name=api.env.host, + ) + krb.pkinit_enable() + def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb): # create a temp nssdb with NSSDatabase() as tempnssdb: From 1ab63da4148b17a089c87876b7af50feda77266c Mon Sep 17 00:00:00 2001 From: Jan Cholasta <jchol...@redhat.com> Date: Mon, 5 Jun 2017 12:41:02 +0000 Subject: [PATCH 2/3] 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 --- 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 1446dfbb7c..a637d287c6 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -1196,6 +1196,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 @@ -1259,6 +1260,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 493e5ff4a8..47ecc14d73 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 0000000000..5b2413bd7c --- /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 0d06ec7306..2dac9ac716 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 0000000000..5018ce8aa3 --- /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] <enable|disable|status> +.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 0000000000..428c0e3476 --- /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 <enable|disable|status>" + 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 a1053d55cc..6b51e65d1e 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -451,6 +451,30 @@ def pkinit_enable(self): 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, From 028d383e018b977e60f8d862f8de9b2efbd1e14a Mon Sep 17 00:00:00 2001 From: Jan Cholasta <jchol...@redhat.com> Date: Mon, 5 Jun 2017 12:42:52 +0000 Subject: [PATCH 3/3] server upgrade: do not enable PKINIT by default Enabling PKINIT often fails during server upgrade when requesting the KDC certificate. Now that PKINIT can be enabled post-install using ipa-pkinit-manage, avoid the upgrade failure by not enabling PKINIT by default. https://pagure.io/freeipa/issue/7000 --- ipaserver/install/server/upgrade.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 3e2abefc21..870bc08c13 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1523,14 +1523,8 @@ def add_default_caacl(ca): def setup_pkinit(krb): root_logger.info("[Setup PKINIT]") - pkinit_is_enabled = krbinstance.is_pkinit_enabled() - ca_is_enabled = api.Command.ca_is_enabled()['result'] - - if not pkinit_is_enabled: - if ca_is_enabled: - krb.issue_ipa_ca_signed_pkinit_certs() - else: - krb.issue_selfsigned_pkinit_certs() + if not krbinstance.is_pkinit_enabled(): + krb.issue_selfsigned_pkinit_certs() aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD, loadpath=paths.USR_SHARE_IPA_DIR)
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org