Do not use ldapi in certificate renewal scripts.

This prevents SELinux denials when accessing the ldapi socket.

Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Jan Cholasta 2014-07-18 11:01:13 +02:00 committed by Petr Viktorin
parent e16d2623ae
commit 7086183519
4 changed files with 106 additions and 81 deletions

View File

@ -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())

View File

@ -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)
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)
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)
ca = cainstance.CAInstance(host_name=api.env.host, ldapi=False)
if ca.is_renewal_master():
cainstance.update_people_entry(cert)
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
conn.connect(ccache=ccache)
dn = DN(('cn', 'CAcert'), ('cn', 'ipa'), ('cn', 'etc'),
api.env.basedn)
if nickname == 'auditSigningCert cert-pki-ca':
# Fix trust on the audit cert
try:
entry = conn.get_entry(dn, attrs_list=['cACertificate;binary'])
entry['cACertificate;binary'] = [cert]
conn.update_entry(entry)
except errors.EmptyModlist:
pass
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:
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

View File

@ -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)
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)
# Load it into dogtag
cainstance.update_people_entry(dercert)
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")

View File

@ -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