From 7086183519bd82ef1e277ceb3ee45438c6695159 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Fri, 18 Jul 2014 11:01:13 +0200 Subject: Do not use ldapi in certificate renewal scripts. This prevents SELinux denials when accessing the ldapi socket. Reviewed-By: Rob Crittenden --- .../certmonger/dogtag-ipa-ca-renew-agent-submit | 50 +++++++------ install/restart_scripts/renew_ca_cert | 83 +++++++++++----------- install/restart_scripts/renew_ra_cert | 35 ++++++--- ipaserver/install/cainstance.py | 21 +++--- 4 files changed, 107 insertions(+), 82 deletions(-) diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit index 6fb9d7971..2ff90494c 100755 --- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit +++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit @@ -37,7 +37,7 @@ from ipapython.dn import DN from ipalib import api, errors, pkcs10, x509 from ipaplatform.paths import paths from ipaserver.plugins.ldap2 import ldap2 -from ipaserver.install import cainstance, certs +from ipaserver.install import cainstance # This is a certmonger CA helper script for IPA CA subsystem cert renewal. See # https://git.fedorahosted.org/cgit/certmonger.git/tree/doc/submit.txt for more @@ -56,20 +56,13 @@ OPERATION_NOT_SUPPORTED_BY_HELPER = 6 @contextlib.contextmanager def ldap_connect(): conn = None - tmpdir = tempfile.mkdtemp(prefix="tmp-") try: - principal = str('host/%s@%s' % (api.env.host, api.env.realm)) - ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, - principal) - conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri) - conn.connect(ccache=ccache) - + conn.connect(ccache=os.environ['KRB5CCNAME']) yield conn finally: if conn is not None and conn.isconnected(): conn.disconnect() - shutil.rmtree(tmpdir) def request_cert(): """ @@ -286,7 +279,7 @@ def renew_ca_cert(): state = 'retrieve' if is_self_signed: - ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR) + ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False) if ca.is_renewal_master(): state = 'request' elif operation == 'POLL': @@ -331,20 +324,31 @@ def main(): api.bootstrap(context='renew') api.finalize() - profile = os.environ.get('CERTMONGER_CA_PROFILE') - if profile: - handler = handlers.get(profile, request_and_store_cert) - else: - ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR) - if ca.is_renewal_master(): - handler = request_and_store_cert - else: - handler = retrieve_cert + operation = os.environ.get('CERTMONGER_OPERATION') + if operation not in ('SUBMIT', 'POLL'): + return OPERATION_NOT_SUPPORTED_BY_HELPER - res = handler() - for item in res[1:]: - print item - return res[0] + tmpdir = tempfile.mkdtemp(prefix="tmp-") + try: + principal = str('host/%s@%s' % (api.env.host, api.env.realm)) + ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, principal) + + profile = os.environ.get('CERTMONGER_CA_PROFILE') + if profile: + handler = handlers.get(profile, request_and_store_cert) + else: + ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False) + if ca.is_renewal_master(): + handler = request_and_store_cert + else: + handler = retrieve_cert + + res = handler() + for item in res[1:]: + print item + return res[0] + finally: + shutil.rmtree(tmpdir) try: sys.exit(main()) diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert index 9e63ef8da..b66cfa292 100644 --- a/install/restart_scripts/renew_ca_cert +++ b/install/restart_scripts/renew_ca_cert @@ -72,50 +72,53 @@ def main(): cainstance.update_cert_config(nickname, cert, configured_constants) - ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR) - if ca.is_renewal_master(): - cainstance.update_people_entry(cert) - - if nickname == 'auditSigningCert cert-pki-ca': - # Fix trust on the audit cert - try: - db.run_certutil(['-M', - '-n', nickname, - '-t', 'u,u,Pu']) - syslog.syslog( - syslog.LOG_NOTICE, - "Updated trust on certificate %s in %s" % (nickname, db.secdir)) - except ipautil.CalledProcessError: - syslog.syslog( - syslog.LOG_ERR, - "Updating trust on certificate %s failed in %s" % - (nickname, db.secdir)) - elif nickname == 'caSigningCert cert-pki-ca' and ca.is_renewal_master(): - # Update CA certificate in LDAP - tmpdir = tempfile.mkdtemp(prefix="tmp-") - try: - principal = str('host/%s@%s' % (api.env.host, api.env.realm)) - ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, - principal) + tmpdir = tempfile.mkdtemp(prefix="tmp-") + try: + principal = str('host/%s@%s' % (api.env.host, api.env.realm)) + ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, + principal) - conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri) - conn.connect(ccache=ccache) + ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False) + if ca.is_renewal_master(): + cainstance.update_people_entry(cert) - dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), - api.env.basedn) + if nickname == 'auditSigningCert cert-pki-ca': + # Fix trust on the audit cert + try: + db.run_certutil(['-M', + '-n', nickname, + '-t', 'u,u,Pu']) + syslog.syslog( + syslog.LOG_NOTICE, + "Updated trust on certificate %s in %s" % + (nickname, db.secdir)) + except ipautil.CalledProcessError: + syslog.syslog( + syslog.LOG_ERR, + "Updating trust on certificate %s failed in %s" % + (nickname, db.secdir)) + elif nickname == 'caSigningCert cert-pki-ca' and ca.is_renewal_master(): + # Update CA certificate in LDAP try: - entry = conn.get_entry(dn, attrs_list=['cACertificate;binary']) - entry['cACertificate;binary'] = [cert] - conn.update_entry(entry) - except errors.EmptyModlist: - pass + conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri) + conn.connect(ccache=ccache) - conn.disconnect() - except Exception, e: - syslog.syslog( - syslog.LOG_ERR, "Updating CA certificate failed: %s" % e) - finally: - shutil.rmtree(tmpdir) + dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'), + api.env.basedn) + try: + entry = conn.get_entry( + dn, attrs_list=['cACertificate;binary']) + entry['cACertificate;binary'] = [cert] + conn.update_entry(entry) + except errors.EmptyModlist: + pass + + conn.disconnect() + except Exception, e: + syslog.syslog( + syslog.LOG_ERR, "Updating CA certificate failed: %s" % e) + finally: + shutil.rmtree(tmpdir) # Now we can start the CA. Using the services start should fire # off the servlet to verify that the CA is actually up and responding so diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert index fb4470588..6d4b81a53 100644 --- a/install/restart_scripts/renew_ra_cert +++ b/install/restart_scripts/renew_ra_cert @@ -22,11 +22,15 @@ import sys import syslog +import tempfile +import shutil import traceback +from ipapython import ipautil from ipalib import api from ipaserver.install import certs, cainstance from ipaplatform import services +from ipaplatform.paths import paths nickname = 'ipaCert' @@ -34,17 +38,26 @@ def main(): api.bootstrap(context='restart') api.finalize() - ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR) - if ca.is_renewal_master(): - # Fetch the new certificate - db = certs.CertDB(api.env.realm) - dercert = db.get_cert_from_db(nickname, pem=False) - if not dercert: - syslog.syslog(syslog.LOG_ERR, 'No certificate %s found.' % nickname) - sys.exit(1) - - # Load it into dogtag - cainstance.update_people_entry(dercert) + tmpdir = tempfile.mkdtemp(prefix="tmp-") + try: + principal = str('host/%s@%s' % (api.env.host, api.env.realm)) + ccache = ipautil.kinit_hostprincipal(paths.KRB5_KEYTAB, tmpdir, + principal) + + ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False) + if ca.is_renewal_master(): + # Fetch the new certificate + db = certs.CertDB(api.env.realm) + dercert = db.get_cert_from_db(nickname, pem=False) + if not dercert: + syslog.syslog( + syslog.LOG_ERR, "No certificate %s found." % nickname) + sys.exit(1) + + # Load it into dogtag + cainstance.update_people_entry(dercert) + finally: + shutil.rmtree(tmpdir) # Now restart Apache so the new certificate is available syslog.syslog(syslog.LOG_NOTICE, "Restarting httpd") diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 7e2572d97..997281f92 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -348,20 +348,21 @@ class CAInstance(service.Service): 2 = have signed cert, continue installation """ - def __init__(self, realm, ra_db, dogtag_constants=None): + def __init__(self, realm=None, ra_db=None, dogtag_constants=None, + host_name=None, dm_password=None, ldapi=True): if dogtag_constants is None: dogtag_constants = dogtag.configured_constants() service.Service.__init__(self, - '%sd' % dogtag_constants.PKI_INSTANCE_NAME, - service_desc="certificate server" - ) + '%sd' % dogtag_constants.PKI_INSTANCE_NAME, + service_desc="certificate server", + dm_password=dm_password, + ldapi=ldapi) self.dogtag_constants = dogtag_constants self.realm = realm - self.dm_password = None self.admin_password = None - self.fqdn = None + self.fqdn = host_name self.domain = None self.pkcs12_info = None self.clone = False @@ -376,11 +377,15 @@ class CAInstance(service.Service): # The same database is used for mod_nss because the NSS context # will already have been initialized by Apache by the time # mod_python wants to do things. - self.canickname = get_ca_nickname(realm) + self.canickname = None + if realm: + self.canickname = get_ca_nickname(realm) self.basedn = DN(('o', 'ipaca')) self.ca_agent_db = tempfile.mkdtemp(prefix = "tmp-") self.ra_agent_db = ra_db - self.ra_agent_pwd = self.ra_agent_db + "/pwdfile.txt" + self.ra_agent_pwd = None + if ra_db: + self.ra_agent_pwd = ra_db + "/pwdfile.txt" self.ds_port = DEFAULT_DSPORT self.security_domain_name = "IPA" self.server_root = dogtag_constants.SERVER_ROOT -- cgit