summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--freeipa.spec.in7
-rw-r--r--install/Makefile.am1
-rw-r--r--install/certmonger/Makefile.am14
-rw-r--r--install/certmonger/dogtag-ipa-retrieve-agent-submit80
-rw-r--r--install/conf/Makefile.am3
-rw-r--r--install/conf/ca_renewal6
-rw-r--r--install/configure.ac1
-rw-r--r--install/restart_scripts/Makefile.am3
-rw-r--r--install/restart_scripts/renew_ca_cert93
-rw-r--r--install/restart_scripts/renew_ra_cert96
-rw-r--r--install/restart_scripts/restart_dirsrv25
-rw-r--r--install/restart_scripts/restart_httpd25
-rw-r--r--install/restart_scripts/restart_pkicad50
-rw-r--r--install/share/bootstrap-template.ldif6
-rw-r--r--install/share/default-aci.ldif10
-rwxr-xr-xinstall/tools/ipa-replica-install1
-rw-r--r--install/tools/ipa-upgradeconfig52
-rw-r--r--install/updates/21-ca_renewal_container.update8
-rw-r--r--install/updates/40-delegation.update4
-rw-r--r--install/updates/Makefile.am1
-rw-r--r--ipalib/x509.py8
-rw-r--r--ipapython/certmonger.py65
-rw-r--r--ipapython/ipautil.py23
-rw-r--r--ipapython/platform/base.py2
-rw-r--r--ipapython/platform/fedora16.py1
-rw-r--r--ipaserver/install/cainstance.py147
-rw-r--r--selinux/ipa_dogtag/ipa_dogtag.te10
27 files changed, 724 insertions, 18 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 719932d4b..6b24a0b0d 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -249,7 +249,7 @@ Requires: xmlrpc-c
%endif
%endif
Requires: sssd >= 1.8.0
-Requires: certmonger >= 0.53
+Requires: certmonger >= 0.58
Requires: nss-tools
Requires: bind-utils
Requires: oddjob-mkhomedir
@@ -571,6 +571,7 @@ fi
%{_sbindir}/ipactl
%{_sbindir}/ipa-upgradeconfig
%{_sbindir}/ipa-compliance
+%{_libexecdir}/certmonger/dogtag-ipa-retrieve-agent-submit
%{_sysconfdir}/cron.d/ipa-compliance
%config(noreplace) %{_sysconfdir}/sysconfig/ipa_memcached
%dir %attr(0700,apache,apache) %{_localstatedir}/run/ipa_memcached/
@@ -633,6 +634,7 @@ fi
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa.conf
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-pki-proxy.conf
+%{_usr}/share/ipa/ca_renewal
%{_usr}/share/ipa/ipa.conf
%{_usr}/share/ipa/ipa-rewrite.conf
%{_usr}/share/ipa/ipa-pki-proxy.conf
@@ -745,6 +747,9 @@ fi
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
%changelog
+* Tue Jul 24 2012 Rob Crittenden <rcritten@redhat.com> - 2.99.0-39
+- Set minimum certmonger to 0.58 for dogtag cert renewal
+
* Wed Jul 18 2012 Alexander Bokovoy <abokovoy@redhat.com> - 2.99.0-38
- Require samba4-devel >= 4.0.0-128 due to passdb API change in beta4
diff --git a/install/Makefile.am b/install/Makefile.am
index 5670f9bd9..54c456a97 100644
--- a/install/Makefile.am
+++ b/install/Makefile.am
@@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = 1.7
NULL =
SUBDIRS = \
+ certmonger \
conf \
html \
migration \
diff --git a/install/certmonger/Makefile.am b/install/certmonger/Makefile.am
new file mode 100644
index 000000000..2023a2aec
--- /dev/null
+++ b/install/certmonger/Makefile.am
@@ -0,0 +1,14 @@
+NULL =
+
+appdir = $(libexecdir)/certmonger/
+app_SCRIPTS = \
+ dogtag-ipa-retrieve-agent-submit \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(app_SCRIPTS) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
diff --git a/install/certmonger/dogtag-ipa-retrieve-agent-submit b/install/certmonger/dogtag-ipa-retrieve-agent-submit
new file mode 100644
index 000000000..24e1844a5
--- /dev/null
+++ b/install/certmonger/dogtag-ipa-retrieve-agent-submit
@@ -0,0 +1,80 @@
+#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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/>.
+
+# The certificate rewewal is done on only one dogtag CA. The others
+# retrieve the updated certificate from IPA.
+
+import os
+import sys
+import shutil
+import tempfile
+import krbV
+import syslog
+from ipalib import api
+from ipalib.dn import DN
+from ipalib import errors
+from ipalib import x509
+from ipapython import services as ipaservices
+from ipapython import ipautil
+from ipaserver.install import certs
+from ipaserver.plugins.ldap2 import ldap2
+import base64
+
+# We cheat and pass in the nickname as the CA profile to execute against.
+# Some way is needed to determine which entry to retrieve from LDAP
+operation = os.environ.get('CERTMONGER_OPERATION')
+nickname = os.environ.get('CERTMONGER_CA_PROFILE')
+
+if operation not in ['SUBMIT', 'POLL']:
+ sys.exit(6) # unsupported operation
+
+api.bootstrap(context='renew')
+api.finalize()
+
+# Update or add it
+tmpdir = tempfile.mkdtemp(prefix = "tmp-")
+try:
+ dn = str(DN(('cn',nickname),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
+ principal = str('host/%s@%s' % (api.env.host, api.env.realm))
+ ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
+ conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
+ conn.connect(ccache=ccache)
+ try:
+ syslog.syslog(syslog.LOG_NOTICE, "Updating certificate for %s" % nickname)
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'])
+ cert = entry_attrs['usercertificate'][0]
+ cert = base64.b64encode(cert)
+ print x509.make_pem(cert)
+ except errors.NotFound:
+ syslog.syslog(syslog.LOG_INFO, "Updated certificate for %s not available" % nickname)
+ # No cert available yet, tell certmonger to wait another 8 hours
+ print 8 * 60 * 60
+ sys.exit(5)
+ finally:
+ conn.disconnect()
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, "Exception trying to retrieve %s: %s" % (nickname, e))
+ # Unhandled error
+ sys.exit(3)
+finally:
+ shutil.rmtree(tmpdir)
+
+sys.exit(0)
diff --git a/install/conf/Makefile.am b/install/conf/Makefile.am
index 5ee3eddb5..06b3b32df 100644
--- a/install/conf/Makefile.am
+++ b/install/conf/Makefile.am
@@ -2,8 +2,9 @@ NULL =
appdir = $(IPA_DATA_DIR)
app_DATA = \
+ ca_renewal \
ipa.conf \
- ipa-pki-proxy.conf \
+ ipa-pki-proxy.conf \
ipa-rewrite.conf \
$(NULL)
diff --git a/install/conf/ca_renewal b/install/conf/ca_renewal
new file mode 100644
index 000000000..57a9e9c24
--- /dev/null
+++ b/install/conf/ca_renewal
@@ -0,0 +1,6 @@
+# A separate helper for fetching dogtag certificates that are renewed on
+# another system.
+id=dogtag-ipa-retrieve-agent-submit
+ca_is_default=0
+ca_type=EXTERNAL
+ca_external_helper=/usr/libexec/certmonger/dogtag-ipa-retrieve-agent-submit
diff --git a/install/configure.ac b/install/configure.ac
index 9e781a684..c5934d93d 100644
--- a/install/configure.ac
+++ b/install/configure.ac
@@ -75,6 +75,7 @@ AC_SUBST(IPA_SYSCONF_DIR)
AC_CONFIG_FILES([
Makefile
+ certmonger/Makefile
conf/Makefile
html/Makefile
migration/Makefile
diff --git a/install/restart_scripts/Makefile.am b/install/restart_scripts/Makefile.am
index abc066b30..210c4863e 100644
--- a/install/restart_scripts/Makefile.am
+++ b/install/restart_scripts/Makefile.am
@@ -4,6 +4,9 @@ appdir = $(libdir)/ipa/certmonger
app_DATA = \
restart_dirsrv \
restart_httpd \
+ restart_pkicad \
+ renew_ca_cert \
+ renew_ra_cert \
$(NULL)
EXTRA_DIST = \
diff --git a/install/restart_scripts/renew_ca_cert b/install/restart_scripts/renew_ca_cert
new file mode 100644
index 000000000..d3b756042
--- /dev/null
+++ b/install/restart_scripts/renew_ca_cert
@@ -0,0 +1,93 @@
+#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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 os
+import sys
+import shutil
+import tempfile
+import krbV
+import syslog
+from ipalib import api
+from ipalib.dn import DN
+from ipalib import errors
+from ipapython import services as ipaservices
+from ipapython import ipautil
+from ipaserver.install import certs
+from ipaserver.plugins.ldap2 import ldap2
+from ipaserver.install.cainstance import update_cert_config
+
+nickname = sys.argv[1]
+
+api.bootstrap(context='restart')
+api.finalize()
+
+# Fetch the new certificate
+db = certs.CertDB(api.env.realm, nssdir='/var/lib/pki-ca/alias')
+cert = db.get_cert_from_db(nickname, pem=False)
+
+if not cert:
+ syslog.syslog(syslog.LOG_ERR, 'No certificate %s found.' % nickname)
+ sys.exit(1)
+
+# Update or add it
+tmpdir = tempfile.mkdtemp(prefix = "tmp-")
+try:
+ dn = str(DN(('cn',nickname),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
+ principal = str('host/%s@%s' % (api.env.host, api.env.realm))
+ ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
+ conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
+ conn.connect(ccache=ccache)
+ try:
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'])
+ entry_attrs['usercertificate'] = cert
+ conn.update_entry(dn, entry_attrs, normalize=False)
+ except errors.NotFound:
+ entry_attrs = dict(objectclass=['top', 'pkiuser', 'nscontainer'],
+ usercertificate=cert)
+ conn.add_entry(dn, entry_attrs, normalize=False)
+ except errors.EmptyModlist:
+ pass
+ conn.disconnect()
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s' % e)
+finally:
+ shutil.rmtree(tmpdir)
+
+# Fix permissions on the audit cert if we're updating it
+if nickname == 'auditSigningCert cert-pki-ca':
+ db = certs.CertDB(api.env.realm, nssdir='/var/lib/pki-ca/alias')
+ args = ['-M',
+ '-n', nickname,
+ '-t', 'u,u,Pu',
+ ]
+ try:
+ db.run_certutil(args)
+ except ipautil.CalledProcessError:
+ syslog.syslog(syslog.LOG_ERR, 'Updating trust on certificate %s failed in %s' % (nickname, db.secdir))
+
+update_cert_config(nickname, cert)
+
+syslog.syslog(syslog.LOG_NOTICE, 'certmonger restarted pki-cad instance pki-ca')
+
+try:
+ ipaservices.knownservices.pki_cad.restart('pki-ca')
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, "Cannot restart pki-cad: %s" % str(e))
diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
new file mode 100644
index 000000000..2fcf1a79b
--- /dev/null
+++ b/install/restart_scripts/renew_ra_cert
@@ -0,0 +1,96 @@
+#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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 sys
+import shutil
+import tempfile
+import syslog
+from ipapython import services as ipaservices
+from ipapython.certmonger import get_pin
+from ipapython import ipautil
+from ipaserver.install import certs
+from ipaserver.install.cainstance import DEFAULT_DSPORT
+from ipalib import api
+from ipalib.dn import DN
+from ipalib import x509
+from ipalib import errors
+from ipaserver.plugins.ldap2 import ldap2
+
+api.bootstrap(context='restart')
+api.finalize()
+
+# Fetch the new certificate
+db = certs.CertDB(api.env.realm)
+cert = db.get_cert_from_db('ipaCert', pem=False)
+serial_number = x509.get_serial_number(cert, datatype=x509.DER)
+subject = x509.get_subject(cert, datatype=x509.DER)
+issuer = x509.get_issuer(cert, datatype=x509.DER)
+
+# Load it into dogtag
+dn = str(DN(('uid','ipara'),('ou','People'),('o','ipaca')))
+
+try:
+ dm_password = get_pin('internaldb')
+except IOError, e:
+ syslog.syslog(syslog.LOG_ERR, 'Unable to determine PIN for CA instance: %s' % e)
+ sys.exit(1)
+
+try:
+ conn = ldap2(shared_instance=False, ldap_uri='ldap://localhost:%d' % DEFAULT_DSPORT)
+ conn.connect(bind_dn='cn=directory manager', bind_pw=dm_password)
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'], normalize=False)
+ entry_attrs['usercertificate'].append(cert)
+ entry_attrs['description'] = '2;%d;%s;%s' % (serial_number, issuer, subject)
+ conn.update_entry(dn, entry_attrs, normalize=False)
+ conn.disconnect()
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, 'Updating agent entry failed: %s' % e)
+ sys.exit(1)
+
+# Store it in the IPA LDAP server
+tmpdir = tempfile.mkdtemp(prefix = "tmp-")
+try:
+ dn = str(DN(('cn','ipaCert'),('cn=ca_renewal,cn=ipa,cn=etc'),(api.env.basedn)))
+ principal = str('host/%s@%s' % (api.env.host, api.env.realm))
+ ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
+ conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
+ conn.connect(ccache=ccache)
+ try:
+ (entry_dn, entry_attrs) = conn.get_entry(dn, ['usercertificate'])
+ entry_attrs['usercertificate'] = cert
+ conn.update_entry(dn, entry_attrs, normalize=False)
+ except errors.NotFound:
+ entry_attrs = dict(objectclass=['top', 'pkiuser', 'nscontainer'],
+ usercertificate=cert)
+ conn.add_entry(dn, entry_attrs, normalize=False)
+ except errors.EmptyModlist:
+ pass
+ conn.disconnect()
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s' % e)
+finally:
+ shutil.rmtree(tmpdir)
+
+# Now restart Apache so the new certificate is available
+try:
+ ipaservices.knownservices.httpd.restart()
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, "Cannot restart httpd: %s" % str(e))
diff --git a/install/restart_scripts/restart_dirsrv b/install/restart_scripts/restart_dirsrv
index e243583f9..d6bbbbc3f 100644
--- a/install/restart_scripts/restart_dirsrv
+++ b/install/restart_scripts/restart_dirsrv
@@ -1,5 +1,26 @@
#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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 sys
+import syslog
from ipapython import services as ipaservices
try:
@@ -7,7 +28,9 @@ try:
except IndexError:
instance = ""
+syslog.syslog(syslog.LOG_NOTICE, "certmonger restarted dirsrv instance '%s'" % instance)
+
try:
ipaservices.knownservices.dirsrv.restart(instance)
except Exception, e:
- print "Cannot restart dirsrv (instance: '%s'): %s" % (instance, str(e))
+ syslog.syslog(syslog.LOG_ERR, "Cannot restart dirsrv (instance: '%s'): %s" % (instance, str(e)))
diff --git a/install/restart_scripts/restart_httpd b/install/restart_scripts/restart_httpd
index a53ab6e62..96f80bd8e 100644
--- a/install/restart_scripts/restart_httpd
+++ b/install/restart_scripts/restart_httpd
@@ -1,7 +1,30 @@
#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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 syslog
from ipapython import services as ipaservices
+syslog.syslog(syslog.LOG_NOTICE, 'certmonger restarted httpd')
+
try:
ipaservices.knownservices.httpd.restart()
except Exception, e:
- print "Cannot restart httpd: %s" % str(e)
+ syslog.syslog(syslog.LOG_ERR, "Cannot restart httpd: %s" % str(e))
diff --git a/install/restart_scripts/restart_pkicad b/install/restart_scripts/restart_pkicad
new file mode 100644
index 000000000..070760b16
--- /dev/null
+++ b/install/restart_scripts/restart_pkicad
@@ -0,0 +1,50 @@
+#!/usr/bin/python -E
+#
+# Authors:
+# Rob Crittenden <rcritten@redhat.com>
+#
+# Copyright (C) 2012 Red Hat
+# 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 sys
+import syslog
+from ipapython import services as ipaservices
+from ipaserver.install import certs
+from ipalib import api
+
+nickname = sys.argv[1]
+
+api.bootstrap(context='restart')
+api.finalize()
+
+syslog.syslog(syslog.LOG_NOTICE, "certmonger restarted pki-cad, nickname '%s'" % nickname)
+
+# Fix permissions on the audit cert if we're updating it
+if nickname == 'auditSigningCert cert-pki-ca':
+ db = certs.CertDB(api.env.realm, nssdir='/var/lib/pki-ca/alias')
+ args = ['-M',
+ '-n', nickname,
+ '-t', 'u,u,Pu',
+ ]
+ db.run_certutil(args)
+
+try:
+ # I've seen times where systemd restart does not actually restart
+ # the process. A full stop/start is required. This works around that
+ ipaservices.knownservices.pki_cad.stop('pki-ca')
+ ipaservices.knownservices.pki_cad.start('pki-ca')
+except Exception, e:
+ syslog.syslog(syslog.LOG_ERR, "Cannot restart pki-cad: %s" % str(e))
diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
index 23510c953..aac3f059a 100644
--- a/install/share/bootstrap-template.ldif
+++ b/install/share/bootstrap-template.ldif
@@ -161,6 +161,12 @@ objectClass: nsContainer
objectClass: top
cn: posix-ids
+dn: cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX
+changetype: add
+objectClass: nsContainer
+objectClass: top
+cn: ca_renewal
+
dn: cn=s4u2proxy,cn=etc,$SUFFIX
changetype: add
objectClass: nsContainer
diff --git a/install/share/default-aci.ldif b/install/share/default-aci.ldif
index 870ac12e9..f3ed39599 100644
--- a/install/share/default-aci.ldif
+++ b/install/share/default-aci.ldif
@@ -86,3 +86,13 @@ changetype: modify
add: aci
aci: (targetattr="userPassword || krbPrincipalKey")(version 3.0; acl "Search existence of password and kerberos keys"; allow(search) userdn = "ldap:///all";)
+# Let host add and update CA renewal certificates
+dn: cn=ipa,cn=etc,$SUFFIX
+changetype: modify
+add: aci
+aci: (target="ldap:///cn=*,cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX")(version 3.0; acl "Add CA Certificates for renewals"; allow(add) userdn = "ldap:///fqdn=$FQDN,cn=computers,cn=accounts,$SUFFIX";)
+
+dn: cn=ipa,cn=etc,$SUFFIX
+changetype: modify
+add: aci
+aci: (target="ldap:///cn=*,cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX")(targetattr="userCertificate")(version 3.0; acl "Modify CA Certificates for renewals"; allow(write) userdn = "ldap:///fqdn=$FQDN,cn=computers,cn=accounts,$SUFFIX";)
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 063eea023..c322cb62e 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -461,6 +461,7 @@ def main():
krb = install_krb(config, setup_pkinit=options.setup_pkinit)
http = install_http(config, auto_redirect=options.ui_redirect)
if CA:
+ CA.configure_certmonger_renewal()
CA.import_ra_cert(dir + "/ra.p12")
CA.fix_ra_perms()
ipaservices.knownservices.httpd.restart()
diff --git a/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig
index cfb9a19e3..951bd4854 100644
--- a/install/tools/ipa-upgradeconfig
+++ b/install/tools/ipa-upgradeconfig
@@ -28,6 +28,7 @@ try:
from ipapython import ipautil, sysrestore, version
from ipapython.config import IPAOptionParser
from ipapython.ipa_log_manager import *
+ from ipapython import certmonger
from ipaserver.install import installutils
from ipaserver.install import dsinstance
from ipaserver.install import httpinstance
@@ -43,6 +44,7 @@ try:
import os
import shutil
import fileinput
+ from ipalib import api
import ipalib.errors
except ImportError:
print >> sys.stderr, """\
@@ -430,6 +432,35 @@ def named_enable_serial_autoincrement():
return changed
+def enable_certificate_renewal(realm):
+ """
+ If the CA subsystem certificates are not being tracked for renewal then
+ tell certmonger to start tracking them.
+ """
+ ca = cainstance.CAInstance(realm, certs.NSS_DIR)
+ if not ca.is_configured():
+ root_logger.debug('dogtag not configured')
+ return
+
+ # Using the nickname find the certmonger request_id
+ criteria = (('cert_storage_location', '/etc/httpd/alias', certmonger.NPATH),('cert_nickname', 'ipaCert', None))
+ request_id = certmonger.get_request_id(criteria)
+ if request_id is not None:
+ root_logger.debug('Certificate renewal already configured')
+ return
+
+ if not sysupgrade.get_upgrade_state('dogtag', 'renewal_configured'):
+ if ca.is_master():
+ ca.configure_renewal()
+ else:
+ ca.configure_certmonger_renewal()
+ ca.configure_clone_renewal()
+ ca.configure_agent_renewal()
+ ca.track_servercert()
+ sysupgrade.set_upgrade_state('dogtag', 'renewal_configured', True)
+ ca.restart(cainstance.PKI_INSTANCE_NAME)
+ root_logger.debug('CA subsystem certificate renewal enabled')
+
def main():
"""
Get some basics about the system. If getting those basics fail then
@@ -440,6 +471,9 @@ def main():
if not os.geteuid()==0:
sys.exit("\nYou must be root to run this script.\n")
+ if not installutils.is_ipa_configured():
+ sys.exit(0)
+
safe_options, options = parse_options()
standard_logging_setup('/var/log/ipaupgrade.log', verbose=True,
@@ -448,11 +482,8 @@ def main():
fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
- try:
- krbctx = krbV.default_context()
- except krbV.Krb5Error, e:
- # Unable to get default kerberos realm
- sys.exit(0)
+ api.bootstrap(context='restart')
+ api.finalize()
fqdn = find_hostname()
if fqdn is None:
@@ -464,13 +495,13 @@ def main():
check_certs()
auto_redirect = find_autoredirect(fqdn)
- sub_dict = { "REALM" : krbctx.default_realm, "FQDN": fqdn, "AUTOREDIR": '' if auto_redirect else '#'}
+ sub_dict = { "REALM" : api.env.realm, "FQDN": fqdn, "AUTOREDIR": '' if auto_redirect else '#'}
upgrade(sub_dict, "/etc/httpd/conf.d/ipa.conf", ipautil.SHARE_DIR + "ipa.conf")
upgrade(sub_dict, "/etc/httpd/conf.d/ipa-rewrite.conf", ipautil.SHARE_DIR + "ipa-rewrite.conf")
upgrade(sub_dict, "/etc/httpd/conf.d/ipa-pki-proxy.conf", ipautil.SHARE_DIR + "ipa-pki-proxy.conf", add=True)
upgrade_pki(fstore)
- update_dbmodules(krbctx.default_realm)
+ update_dbmodules(api.env.realm)
uninstall_ipa_kpasswd()
http = httpinstance.HTTPInstance(fstore)
@@ -479,25 +510,26 @@ def main():
memcache = memcacheinstance.MemcacheInstance()
memcache.ldapi = True
- memcache.realm = krbctx.default_realm
+ memcache.realm = api.env.realm
try:
if not memcache.is_configured():
# 389-ds needs to be running to create the memcache instance
# because we record the new service in cn=masters.
ds = dsinstance.DsInstance()
ds.start()
- memcache.create_instance('MEMCACHE', fqdn, None, ipautil.realm_to_suffix(krbctx.default_realm))
+ memcache.create_instance('MEMCACHE', fqdn, None, ipautil.realm_to_suffix(api.env.realm))
except (ldap.ALREADY_EXISTS, ipalib.errors.DuplicateEntry):
pass
cleanup_kdc(fstore)
- upgrade_ipa_profile(krbctx.default_realm)
+ upgrade_ipa_profile(api.env.realm)
changed_psearch = named_enable_psearch()
changed_autoincrement = named_enable_serial_autoincrement()
if changed_psearch or changed_autoincrement:
# configuration has changed, restart the name server
root_logger.info('Changes to named.conf have been made, restart named')
bindinstance.BindInstance(fstore).restart()
+ enable_certificate_renewal(api.env.realm)
if __name__ == '__main__':
installutils.run_script(main, operation_name='ipa-upgradeconfig')
diff --git a/install/updates/21-ca_renewal_container.update b/install/updates/21-ca_renewal_container.update
new file mode 100644
index 000000000..50b92d73d
--- /dev/null
+++ b/install/updates/21-ca_renewal_container.update
@@ -0,0 +1,8 @@
+#
+# Add CA renewal container if not available
+#
+
+dn: cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX
+add:objectClass: top
+add:objectClass: nsContainer
+add:cn: ca_renewal
diff --git a/install/updates/40-delegation.update b/install/updates/40-delegation.update
index de112d99d..1e512d0f7 100644
--- a/install/updates/40-delegation.update
+++ b/install/updates/40-delegation.update
@@ -356,3 +356,7 @@ replace:aci:'(target = "ldap:///uid=*,cn=users,cn=accounts,$SUFFIX")(targetattr
# Don't allow the default 'manage group membership' to be able to manage the
# admins group
replace:aci:'(targetattr = "member")(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Modify Group membership";allow (write) groupdn = "ldap:///cn=Modify Group membership,cn=permissions,cn=pbac,$SUFFIX";)::(targetfilter = "(!(cn=admins))")(targetattr = "member")(target = "ldap:///cn=*,cn=groups,cn=accounts,$SUFFIX")(version 3.0;acl "permission:Modify Group membership";allow (write) groupdn = "ldap:///cn=Modify Group membership,cn=permissions,cn=pbac,$SUFFIX";)'
+
+dn: cn=ipa,cn=etc,$SUFFIX
+add:aci:'(target = "ldap:///cn=*,cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX")(version 3.0; acl "Add CA Certificates for renewals"; allow(add) userdn = "ldap:///fqdn=$FQDN,cn=computers,cn=accounts,$SUFFIX";)'
+add:aci:'(target = "ldap:///cn=*,cn=ca_renewal,cn=ipa,cn=etc,$SUFFIX")(targetattr = "userCertificate")(version 3.0; acl "Modify CA Certificates for renewals"; allow(write) userdn = "ldap:///fqdn=$FQDN,cn=computers,cn=accounts,$SUFFIX";)'
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index e45690f14..bc7945d7a 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -22,6 +22,7 @@ app_DATA = \
20-user_private_groups.update \
20-winsync_index.update \
21-replicas_container.update \
+ 21-ca_renewal_container.update \
30-s4u2proxy.update \
40-delegation.update \
40-dns.update \
diff --git a/ipalib/x509.py b/ipalib/x509.py
index 1274673c3..1b133adfb 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -141,6 +141,14 @@ def get_subject(certificate, datatype=PEM, dbdir=None):
nsscert = load_certificate(certificate, datatype, dbdir)
return nsscert.subject
+def get_issuer(certificate, datatype=PEM, dbdir=None):
+ """
+ Load an X509.3 certificate and get the issuer.
+ """
+
+ nsscert = load_certificate(certificate, datatype, dbdir)
+ return nsscert.issuer
+
def get_serial_number(certificate, datatype=PEM, dbdir=None):
"""
Return the decimal value of the serial number.
diff --git a/ipapython/certmonger.py b/ipapython/certmonger.py
index 22a599ae6..bdc8591e7 100644
--- a/ipapython/certmonger.py
+++ b/ipapython/certmonger.py
@@ -22,6 +22,7 @@
# server certificates created during the IPA server installation.
import os
+import sys
import re
import time
from ipapython import ipautil
@@ -329,6 +330,70 @@ def remove_principal_from_cas():
fp.write(line)
fp.close()
+# Routines specific to renewing dogtag CA certificates
+def get_pin(token):
+ """
+ Dogtag stores its NSS pin in a file formatted as token:PIN.
+
+ The caller is expected to handle any exceptions raised.
+ """
+ filename = '/var/lib/pki-ca/conf/password.conf'
+ with open(filename, 'r') as f:
+ for line in f:
+ (tok, pin) = line.split('=', 1)
+ if token == tok:
+ return pin.strip()
+ return None
+
+def dogtag_start_tracking(ca, nickname, pin, pinfile, secdir, command):
+ """
+ Tell certmonger to start tracking a dogtag CA certificate. These
+ are handled differently because their renewal must be done directly
+ and not through IPA.
+
+ This uses the generic certmonger command getcert so we can specify
+ a different helper.
+
+ command is the script to execute.
+
+ Returns the stdout, stderr and returncode from running ipa-getcert
+
+ This assumes that certmonger is already running.
+ """
+ if not cert_exists(nickname, os.path.abspath(secdir)):
+ raise RuntimeError('Nickname "%s" doesn\'t exist in NSS database "%s"' % (nickname, secdir))
+
+ if command is not None and not os.path.isabs(command):
+ if sys.maxsize > 2**32:
+ libpath = 'lib64'
+ else:
+ libpath = 'lib'
+ command = '/usr/%s/ipa/certmonger/%s' % (libpath, command)
+
+ args = ["/usr/bin/getcert", "start-tracking",
+ "-d", os.path.abspath(secdir),
+ "-n", nickname,
+ "-c", ca,
+ "-C", command,
+ ]
+
+ if pinfile:
+ args.append("-p")
+ args.append(pinfile)
+ else:
+ args.append("-P")
+ args.append(pin)
+
+ if ca == 'dogtag-ipa-retrieve-agent-submit':
+ # We cheat and pass in the nickname as the profile when
+ # renewing on a clone. The submit otherwise doesn't pass in the
+ # nickname and we need some way to find the right entry in LDAP.
+ args.append("-T")
+ args.append(nickname)
+
+ (stdout, stderr, returncode) = ipautil.run(args, nolog=[pin])
+
+
if __name__ == '__main__':
request_id = request_cert("/etc/httpd/alias", "Test", "cn=tiger.example.com,O=IPA", "HTTP/tiger.example.com@EXAMPLE.COM")
csr = get_request_value(request_id, 'csr')
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 22c8e2937..bed5435b5 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -42,6 +42,7 @@ import xmlrpclib
import datetime
import netaddr
import time
+import krbV
from dns import resolver, rdatatype
from dns.exception import DNSException
@@ -1086,3 +1087,25 @@ def wait_for_open_socket(socket_name, timeout=0):
time.sleep(1)
else:
raise e
+
+def kinit_hostprincipal(keytab, ccachedir, principal):
+ """
+ Given a ccache directory and a principal kinit as that user.
+
+ This blindly overwrites the current CCNAME so if you need to save
+ it do so before calling this function.
+
+ Thus far this is used to kinit as the local host.
+ """
+ try:
+ ccache_file = 'FILE:%s/ccache' % ccachedir
+ krbcontext = krbV.default_context()
+ ktab = krbV.Keytab(name=keytab, context=krbcontext)
+ princ = krbV.Principal(name=principal, context=krbcontext)
+ os.environ['KRB5CCNAME'] = ccache_file
+ ccache = krbV.CCache(name=ccache_file, context=krbcontext, primary_principal=princ)
+ ccache.init(princ)
+ ccache.init_creds_keytab(keytab=ktab, principal=princ)
+ return ccache_file
+ except krbV.Krb5Error, e:
+ raise StandardError('Error initializing principal %s in %s: %s' % (principal, keytab, str(e)))
diff --git a/ipapython/platform/base.py b/ipapython/platform/base.py
index 6f9d3867a..8c694ac04 100644
--- a/ipapython/platform/base.py
+++ b/ipapython/platform/base.py
@@ -25,7 +25,7 @@ from ipalib.plugable import MagicDict
wellknownservices = ['certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
'messagebus', 'nslcd', 'nscd', 'ntpd', 'portmap',
'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
- 'rpcidmapd']
+ 'rpcidmapd', 'pki_cad']
# The common ports for these services. This is used to wait for the
diff --git a/ipapython/platform/fedora16.py b/ipapython/platform/fedora16.py
index 8b730e41c..100bbb2ab 100644
--- a/ipapython/platform/fedora16.py
+++ b/ipapython/platform/fedora16.py
@@ -60,6 +60,7 @@ system_units['dirsrv'] = 'dirsrv@.service'
system_units['pkids'] = 'dirsrv@PKI-IPA.service'
# Our PKI instance is pki-cad@pki-ca.service
system_units['pki-cad'] = 'pki-cad@pki-ca.service'
+system_units['pki_cad'] = system_units['pki-cad']
class Fedora16Service(systemd.SystemdService):
def __init__(self, service_name):
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 62c1dc4d0..2644689a0 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -37,6 +37,7 @@ import stat
import socket
from ipapython import dogtag
from ipapython.certdb import get_ca_nickname
+from ipapython import certmonger
from ipalib import pkcs10, x509
from ipalib.dn import DN
import subprocess
@@ -324,7 +325,7 @@ class CADSInstance(service.Service):
# We only handle one server cert
self.nickname = server_certs[0][0]
self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
- dsdb.track_server_cert(self.nickname, self.principal, dsdb.passwd_fname)
+ dsdb.track_server_cert(self.nickname, self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid)
def create_certdb(self):
"""
@@ -337,7 +338,7 @@ class CADSInstance(service.Service):
cadb.export_ca_cert('ipaCert', False)
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
self.dercert = dsdb.create_server_cert("Server-Cert", self.fqdn, cadb)
- dsdb.track_server_cert("Server-Cert", self.principal, dsdb.passwd_fname)
+ dsdb.track_server_cert("Server-Cert", self.principal, dsdb.passwd_fname, 'restart_dirsrv %s' % self.serverid)
dsdb.create_pin_file()
def enable_ssl(self):
@@ -404,6 +405,24 @@ class CADSInstance(service.Service):
# At one time we removed this user on uninstall. That can potentially
# orphan files, or worse, if another useradd runs in the intermim,
# cause files to have a new owner.
+ cmonger = ipaservices.knownservices.certmonger
+ ipaservices.knownservices.messagebus.start()
+ cmonger.start()
+
+ for nickname in ['Server-Cert cert-pki-ca',
+ 'auditSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']:
+ try:
+ certmonger.stop_tracking('/var/lib/pki-ca/alias', nickname=nickname)
+ except (ipautil.CalledProcessError, RuntimeError), e:
+ root_logger.error("certmonger failed to stop tracking certificate: %s" % str(e))
+
+ try:
+ certmonger.stop_tracking('/etc/httpd/alias', nickname='ipaCert')
+ except (ipautil.CalledProcessError, RuntimeError), e:
+ root_logger.error("certmonger failed to stop tracking certificate: %s" % str(e))
+ cmonger.stop()
class CAInstance(service.Service):
"""
@@ -526,6 +545,11 @@ class CAInstance(service.Service):
self.step("requesting RA certificate from CA", self.__request_ra_certificate)
self.step("issuing RA agent certificate", self.__issue_ra_cert)
self.step("adding RA agent as a trusted user", self.__configure_ra)
+ self.step("configure certificate renewals", self.configure_renewal)
+ else:
+ self.step("configure certmonger for renewals", self.configure_certmonger_renewal)
+ self.step("configure clone certificate renewals", self.configure_clone_renewal)
+ self.step("configure Server-Cert certificate renewal", self.track_servercert)
self.step("Configure HTTP to proxy connections", self.__http_proxy)
self.start_creation("Configuring certificate server", 210)
@@ -797,6 +821,18 @@ class CAInstance(service.Service):
finally:
os.remove(agent_name)
+ self.configure_agent_renewal()
+
+ def configure_agent_renewal(self):
+ """
+ Set up the agent cert for renewal. No need to make any changes to
+ the dogtag LDAP here since the originator will do that so we
+ only call restart_httpd after retrieving the cert.
+
+ On upgrades this needs to be called from ipa-upgradeconfig.
+ """
+ certmonger.dogtag_start_tracking('dogtag-ipa-retrieve-agent-submit', 'ipaCert', None, '/etc/httpd/alias/pwdfile.txt', '/etc/httpd/alias', 'restart_httpd')
+
def __configure_ra(self):
# Create an RA user in the CA LDAP server and add that user to
# the appropriate groups so it can issue certificates without
@@ -1058,6 +1094,8 @@ class CAInstance(service.Service):
# cause files to have a new owner.
user_exists = self.restore_state("user_exists")
+ installutils.remove_file("/var/lib/certmonger/cas/ca_renewal")
+
def publish_ca_cert(self, location):
args = ["-L", "-n", self.canickname, "-a"]
(cert, err, returncode) = self.__run_certutil(args)
@@ -1070,6 +1108,77 @@ class CAInstance(service.Service):
shutil.copy(ipautil.SHARE_DIR + "ipa-pki-proxy.conf",
HTTPD_CONFD + "ipa-pki-proxy.conf")
+ def track_servercert(self):
+ try:
+ pin = certmonger.get_pin('internal')
+ except IOError, e:
+ raise RuntimeError('Unable to determine PIN for CA instance: %s' % str(e))
+ certmonger.dogtag_start_tracking('dogtag-ipa-renew-agent', 'Server-Cert cert-pki-ca', pin, None, '/var/lib/pki-ca/alias', 'restart_pkicad "Server-Cert cert-pki-ca"')
+
+ def configure_renewal(self):
+ cmonger = ipaservices.knownservices.certmonger
+ cmonger.enable()
+ ipaservices.knownservices.messagebus.start()
+ cmonger.start()
+
+ try:
+ pin = certmonger.get_pin('internal')
+ except IOError, e:
+ raise RuntimeError('Unable to determine PIN for CA instance: %s' % str(e))
+
+ # Server-Cert cert-pki-ca is renewed per-server
+ for nickname in ['auditSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']:
+ certmonger.dogtag_start_tracking('dogtag-ipa-renew-agent', nickname, pin, None, '/var/lib/pki-ca/alias', 'renew_ca_cert "%s"' % nickname)
+
+ # Set up the agent cert for renewal
+ certmonger.dogtag_start_tracking('dogtag-ipa-renew-agent', 'ipaCert', None, '/etc/httpd/alias/pwdfile.txt', '/etc/httpd/alias', 'renew_ra_cert')
+
+ def configure_certmonger_renewal(self):
+ """
+ Create a new CA type for certmonger that will retrieve updated
+ certificates from the dogtag master server.
+ """
+ target_fname = '/var/lib/certmonger/cas/ca_renewal'
+ if ipautil.file_exists(target_fname):
+ # This CA can be configured either during initial CA installation
+ # if the replica is created with --setup-ca or when Apache is
+ # being configured if not.
+ return
+ txt = ipautil.template_file(ipautil.SHARE_DIR + "ca_renewal", dict())
+ fd = open(target_fname, "w")
+ fd.write(txt)
+ fd.close()
+ os.chmod(target_fname, 0600)
+ ipaservices.restore_context(target_fname)
+
+ cmonger = ipaservices.knownservices.certmonger
+ cmonger.enable()
+ ipaservices.knownservices.messagebus.start()
+ cmonger.restart()
+
+ def configure_clone_renewal(self):
+ """
+ The actual renewal is done on the master. On the clone side we
+ use a separate certmonger CA that polls LDAP to see if an updated
+ certificate is available. If it is then it gets installed.
+ """
+
+ try:
+ pin = certmonger.get_pin('internal')
+ except IOError, e:
+ raise RuntimeError('Unable to determine PIN for CA instance: %s' % str(e))
+
+ # Server-Cert cert-pki-ca is renewed per-server
+ for nickname in ['auditSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']:
+ certmonger.dogtag_start_tracking('dogtag-ipa-retrieve-agent-submit', nickname, pin, None, '/var/lib/pki-ca/alias', 'restart_pkicad "%s"' % nickname)
+
+ # The agent renewal is configured in import_ra_cert which is called
+ # after the HTTP instance is created.
+
def enable_subject_key_identifier(self):
"""
See if Subject Key Identifier is set in the profile and if not, add it.
@@ -1109,6 +1218,21 @@ class CAInstance(service.Service):
# No update was done
return False
+ def is_master(self):
+ """
+ There are some tasks that are only done on a single dogtag master.
+ By default this is the first one installed. Use this to determine if
+ that is the case.
+
+ If users have changed their topology so the initial master is either
+ gone or no longer performing certain duties then it is their
+ responsibility to handle changes on upgrades.
+ """
+ master = installutils.get_directive(
+ '/var/lib/pki-ca/conf/CS.cfg', 'subsystem.select', '=')
+
+ return master == 'New'
+
def install_replica_ca(config, postinstall=False):
"""
Install a CA on a replica.
@@ -1179,6 +1303,25 @@ def install_replica_ca(config, postinstall=False):
return (ca, cs)
+def update_cert_config(nickname, cert):
+ """
+ When renewing a CA subsystem certificate the configuration file
+ needs to get the new certificate as well.
+
+ nickname is one of the known nicknames.
+ cert is a DER-encoded certificate.
+ """
+ # The cert directive to update per nickname
+ directives = {'auditSigningCert cert-pki-ca': 'ca.audit_signing.cert',
+ 'ocspSigningCert cert-pki-ca': 'ca.ocsp_signing.cert',
+ 'caSigningCert cert-pki-ca': 'ca.signing.cert',
+ 'Server-Cert cert-pki-ca': 'ca.sslserver.cert' }
+
+ installutils.set_directive('/var/lib/%s/conf/CS.cfg' % PKI_INSTANCE_NAME,
+ directives[nickname],
+ base64.b64encode(cert),
+ quotes=False, separator='=')
+
if __name__ == "__main__":
standard_logging_setup("install.log")
cs = CADSInstance()
diff --git a/selinux/ipa_dogtag/ipa_dogtag.te b/selinux/ipa_dogtag/ipa_dogtag.te
index 3750e4d10..1404e17ca 100644
--- a/selinux/ipa_dogtag/ipa_dogtag.te
+++ b/selinux/ipa_dogtag/ipa_dogtag.te
@@ -1,15 +1,19 @@
-module ipa_dogtag 1.4;
+module ipa_dogtag 1.5;
require {
type httpd_t;
type cert_t;
type pki_ca_t;
type pki_ca_var_lib_t;
+ type certmonger_t;
class dir write;
class dir add_name;
class dir remove_name;
class dir search;
class dir getattr;
+ class file read;
+ class file getattr;
+ class file open;
class file create;
class file write;
class file rename;
@@ -35,3 +39,7 @@ allow pki_ca_t cert_t:lnk_file unlink;
# Let apache read the CRLs
allow httpd_t pki_ca_var_lib_t:dir { search getattr };
+
+# Let certmonger manage the dogtag certificate database for renewals
+allow certmonger_t pki_ca_var_lib_t:dir { search getattr} ;
+allow certmonger_t pki_ca_var_lib_t:file { read write getattr open };