summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Kosek <mkosek@redhat.com>2012-10-08 15:58:48 +0200
committerMartin Kosek <mkosek@redhat.com>2012-10-09 16:00:01 +0200
commit74ebd0fd75fababe7d080080ef019b53e96c0c4f (patch)
treeced59ca3583b0d9092f58e7d3ec903c417ed7a91
parent9bb927eb1cca3fd4ac4768b2ef53aab75b848bd6 (diff)
downloadfreeipa-74ebd0fd75fababe7d080080ef019b53e96c0c4f.tar.gz
freeipa-74ebd0fd75fababe7d080080ef019b53e96c0c4f.tar.xz
freeipa-74ebd0fd75fababe7d080080ef019b53e96c0c4f.zip
Move CRL publish directory to IPA owned directory
Currently, CRL files are being exported to /var/lib/pki-ca sub-directory, which is then served by httpd to clients. However, this approach has several disadvantages: * We depend on pki-ca directory structure and relevant permissions. If pki-ca changes directory structure or permissions on upgrade, IPA may break. This is also a root cause of the latest error, where the pki-ca directory does not have X permission for others and CRL publishing by httpd breaks. * Since the directory is not static and is generated during ipa-server-install, RPM upgrade of IPA packages report errors when defining SELinux policy for these directories. Move CRL publish directory to /var/lib/ipa/pki-ca/publish (common for both dogtag 9 and 10) which is created on RPM upgrade, i.e. SELinux policy configuration does not report any error. The new CRL publish directory is used for both new IPA installs and upgrades, where contents of the directory (CRLs) is first migrated to the new location and then the actual configuration change is made. https://fedorahosted.org/freeipa/ticket/3144
-rw-r--r--freeipa.spec.in6
-rw-r--r--install/Makefile.am3
-rw-r--r--install/conf/ipa.conf2
-rw-r--r--install/tools/ipa-upgradeconfig103
-rw-r--r--ipapython/dogtag.py4
-rw-r--r--ipaserver/install/cainstance.py49
-rw-r--r--selinux/ipa_dogtag/ipa_dogtag.fc3
7 files changed, 146 insertions, 24 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 7c8314a04..cc27ffe43 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -397,6 +397,7 @@ rm %{buildroot}/%{_libdir}/samba/pdb/ipasam.la
mkdir -p %{buildroot}/%{_sysconfdir}/ipa/html
mkdir -p %{buildroot}/%{_localstatedir}/cache/ipa/sysrestore
mkdir -p %{buildroot}/%{_localstatedir}/cache/ipa/sysupgrade
+mkdir -p %{buildroot}/%{_localstatedir}/cache/ipa/pki-ca/publish
mkdir %{buildroot}%{_usr}/share/ipa/html/
ln -s ../../../..%{_sysconfdir}/ipa/html/ffconfig.js \
%{buildroot}%{_usr}/share/ipa/html/ffconfig.js
@@ -694,6 +695,8 @@ fi
%dir %{_localstatedir}/lib/ipa
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysupgrade
+%attr(755,root,root) %dir %{_localstatedir}/lib/ipa/pki-ca
+%attr(755,root,root) %dir %{_localstatedir}/lib/ipa/pki-ca/publish
%dir %{_localstatedir}/cache/ipa
%attr(700,apache,apache) %dir %{_localstatedir}/cache/ipa/sessions
%attr(755,root,root) %{_libdir}/krb5/plugins/kdb/ipadb.so
@@ -783,6 +786,9 @@ fi
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
%changelog
+* Mon Oct 8 2012 Martin Kosek <mkosek@redhat.com> - 2.99.0-48
+- Add directory /var/lib/ipa/pki-ca/publish for CRL published by pki-ca
+
* Mon Oct 1 2012 Martin Kosek <mkosek@redhat.com> - 2.99.0-47
- Require samba packages instead of samba4 packages obsoleted in Fedora 18 and later
- Add libwbclient-devel BuildRequires to pick up libwbclient.h on Fedora 18 and later
diff --git a/install/Makefile.am b/install/Makefile.am
index 184855e64..361318526 100644
--- a/install/Makefile.am
+++ b/install/Makefile.am
@@ -25,6 +25,9 @@ install-exec-local:
chmod 700 $(DESTDIR)$(localstatedir)/lib/ipa/sysupgrade
mkdir -p $(DESTDIR)$(localstatedir)/cache/ipa/sessions
chmod 700 $(DESTDIR)$(localstatedir)/cache/ipa/sessions
+ mkdir -p $(DESTDIR)$(localstatedir)/lib/ipa/pki-ca/publish
+ chmod 755 $(DESTDIR)$(localstatedir)/lib/ipa/pki-ca
+ chmod 755 $(DESTDIR)$(localstatedir)/lib/ipa/pki-ca/publish
uninstall-local:
-rmdir $(DESTDIR)$(localstatedir)/lib/ipa/sysrestore
diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf
index 5cd1d8c59..d3f3446b0 100644
--- a/install/conf/ipa.conf
+++ b/install/conf/ipa.conf
@@ -1,5 +1,5 @@
#
-# VERSION 9 - DO NOT REMOVE THIS LINE
+# VERSION 10 - DO NOT REMOVE THIS LINE
#
# This file may be overwritten on upgrades.
#
diff --git a/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig
index 6c0437180..cb2164c0c 100644
--- a/install/tools/ipa-upgradeconfig
+++ b/install/tools/ipa-upgradeconfig
@@ -25,7 +25,7 @@ Upgrade configuration files to a newer template.
import sys
try:
- from ipapython import ipautil, sysrestore, version
+ from ipapython import ipautil, sysrestore, version, services
from ipapython.config import IPAOptionParser
from ipapython.ipa_log_manager import *
from ipapython import certmonger
@@ -44,6 +44,7 @@ try:
import re
import os
import shutil
+ import pwd
import fileinput
from ipalib import api
import ipalib.errors
@@ -281,12 +282,11 @@ def cleanup_kdc(fstore):
fstore.untrack_file(filename)
root_logger.debug('Uninstalling %s', filename)
-def upgrade_ipa_profile(realm):
+def upgrade_ipa_profile(ca):
"""
Update the IPA Profile provided by dogtag
"""
root_logger.info('[Verifying that CA service certificate profile is updated]')
- ca = cainstance.CAInstance(realm, certs.NSS_DIR)
if ca.is_configured():
if ca.enable_subject_key_identifier():
root_logger.debug('Subject Key Identifier updated, restarting CA')
@@ -433,22 +433,23 @@ def named_enable_serial_autoincrement():
return changed
-def enable_certificate_renewal(realm):
+def enable_certificate_renewal(ca):
"""
If the CA subsystem certificates are not being tracked for renewal then
tell certmonger to start tracking them.
+
+ Returns True when CA needs to be restarted
"""
- ca = cainstance.CAInstance(realm, certs.NSS_DIR)
if not ca.is_configured():
root_logger.debug('dogtag not configured')
- return
+ return False
# 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
+ return False
if not sysupgrade.get_upgrade_state('dogtag', 'renewal_configured'):
if ca.is_master():
@@ -459,8 +460,81 @@ def enable_certificate_renewal(realm):
ca.configure_agent_renewal()
ca.track_servercert()
sysupgrade.set_upgrade_state('dogtag', 'renewal_configured', True)
- ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)
root_logger.debug('CA subsystem certificate renewal enabled')
+ return True
+
+ return False
+
+def copy_crl_file(old_path, new_path=None):
+ """
+ Copy CRL to new location, update permissions and SELinux context
+ """
+ if new_path is None:
+ filename = os.path.basename(old_path)
+ new_path = os.path.join(dogtag.configured_constants().CRL_PUBLISH_PATH,
+ filename)
+ root_logger.debug('copy_crl_file: %s -> %s', old_path, new_path)
+
+ if os.path.islink(old_path):
+ # update symlink to the most most recent CRL file
+ filename = os.path.basename(os.readlink(old_path))
+ realpath = os.path.join(dogtag.configured_constants().CRL_PUBLISH_PATH,
+ filename)
+ root_logger.debug('copy_crl_file: Create symlink %s -> %s',
+ new_path, realpath)
+ os.symlink(realpath, new_path)
+ else:
+ shutil.copy2(old_path, new_path)
+ pent = pwd.getpwnam(cainstance.PKI_USER)
+ os.chown(new_path, pent.pw_uid, pent.pw_gid)
+
+ services.restore_context(new_path)
+
+def migrate_crl_publish_dir(ca):
+ """
+ Move CRL publish dir from /var/lib/pki-ca/publish to IPA controlled tree:
+ /var/lib/ipa/pki-ca/publish
+ """
+ root_logger.info('[Migrate CRL publish directory]')
+ if sysupgrade.get_upgrade_state('dogtag', 'moved_crl_publish_dir'):
+ root_logger.info('CRL tree already moved')
+ return False
+
+ caconfig = dogtag.configured_constants()
+
+ old_publish_dir = installutils.get_directive(caconfig.CS_CFG_PATH,
+ 'ca.publish.publisher.instance.FileBaseCRLPublisher.directory',
+ separator='=')
+
+ if old_publish_dir == caconfig.CRL_PUBLISH_PATH:
+ # publish dir is already updated
+ root_logger.info('Publish directory already set to new location')
+ sysupgrade.set_upgrade_state('dogtag', 'moved_crl_publish_dir', True)
+ return False
+
+ # Prepare target publish dir (permissions, SELinux context)
+ publishdir = ca.prepare_crl_publish_dir()
+
+ # Copy all CRLs to new directory
+ root_logger.info('Copy all CRLs to new publish directory')
+ try:
+ crl_files = cainstance.get_crl_files(old_publish_dir)
+ except OSError, e:
+ root_logger.error('Cannot move CRL files to new directory: %s', e)
+ else:
+ for f in crl_files:
+ try:
+ copy_crl_file(f)
+ except Exception, e:
+ root_logger.error('Cannot move CRL file to new directory: %s', e)
+
+ installutils.set_directive(caconfig.CS_CFG_PATH,
+ 'ca.publish.publisher.instance.FileBaseCRLPublisher.directory',
+ publishdir, quotes=False, separator='=')
+ sysupgrade.set_upgrade_state('dogtag', 'moved_crl_publish_dir', True)
+ root_logger.info('CRL publish directory has been migrated, '
+ 'request pki-ca restart')
+ return True
def main():
"""
@@ -505,6 +579,11 @@ def main():
DOGTAG_PORT=configured_constants.AJP_PORT,
)
+
+ # migrate CRL publish dir before the location in ipa.conf is updated
+ ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR)
+ ca_restart = migrate_crl_publish_dir(ca)
+
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)
@@ -530,14 +609,18 @@ def main():
pass
cleanup_kdc(fstore)
- upgrade_ipa_profile(api.env.realm)
+ upgrade_ipa_profile(ca)
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)
+ ca_restart = ca_restart or enable_certificate_renewal(ca)
+
+ if ca_restart:
+ root_logger.info('pki-ca configuration changed, restart pki-ca')
+ ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)
if __name__ == '__main__':
installutils.run_script(main, operation_name='ipa-upgradeconfig')
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index 22a5a6d19..3bc9e5d5d 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -54,7 +54,7 @@ class Dogtag10Constants(object):
SERVER_ROOT = '/var/lib/pki'
PKI_INSTANCE_NAME = 'pki-tomcat'
PKI_ROOT = '%s/%s' % (SERVER_ROOT, PKI_INSTANCE_NAME)
- CRL_PUBLISH_PATH = '%s/ca/publish' % PKI_ROOT
+ CRL_PUBLISH_PATH = '%s/ipa/pki-ca/publish' % SERVER_ROOT
CS_CFG_PATH = '%s/conf/ca/CS.cfg' % PKI_ROOT
PASSWORD_CONF_PATH = '%s/conf/password.conf' % PKI_ROOT
SERVICE_PROFILE_DIR = '%s/ca/profiles/ca' % PKI_ROOT
@@ -78,7 +78,7 @@ class Dogtag9Constants(object):
SERVER_ROOT = '/var/lib'
PKI_INSTANCE_NAME = 'pki-ca'
PKI_ROOT = '%s/%s' % (SERVER_ROOT, PKI_INSTANCE_NAME)
- CRL_PUBLISH_PATH = '%s/publish' % PKI_ROOT
+ CRL_PUBLISH_PATH = '%s/ipa/pki-ca/publish' % SERVER_ROOT
CS_CFG_PATH = '%s/conf/CS.cfg' % PKI_ROOT
PASSWORD_CONF_PATH = '%s/conf/password.conf' % PKI_ROOT
SERVICE_PROFILE_DIR = '%s/profiles/ca' % PKI_ROOT
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index e08df06a8..c37c261f2 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -48,7 +48,6 @@ import nss.nss as nss
from ipapython import ipautil
from ipapython import nsslib
from ipapython import services as ipaservices
-from ipapython import dogtag
from ipaserver import ipaldap
from ipaserver.install import service
@@ -215,6 +214,23 @@ def get_outputList(data):
return outputdict
+def get_crl_files(path=None):
+ """
+ Traverse dogtag's CRL files in default CRL publish directory or in chosen
+ target directory.
+
+ @param path Custom target directory
+ """
+ if path is None:
+ path = dogtag.configured_constants().CRL_PUBLISH_PATH
+
+ files = os.listdir(path)
+ for f in files:
+ if f == "MasterCRL.bin":
+ yield os.path.join(path, f)
+ elif f.endswith(".der"):
+ yield os.path.join(path, f)
+
class CADSInstance(service.Service):
def __init__(self, host_name=None, realm_name=None, domain_name=None, dm_password=None, dogtag_constants=None):
service.Service.__init__(self, "pkids", dm_password=dm_password, ldapi=False, autobind=service.DISABLED)
@@ -1161,19 +1177,30 @@ class CAInstance(service.Service):
installutils.set_directive(self.dogtag_constants.SIGN_PROFILE,
'auth.instance_id', 'raCertAuth', quotes=False, separator='=')
+ def prepare_crl_publish_dir(self):
+ """
+ Prepare target directory for CRL publishing
+
+ Returns a path to the CRL publishing directory
+ """
+ publishdir = self.dogtag_constants.CRL_PUBLISH_PATH
+ os.chmod(publishdir, 0775)
+ pent = pwd.getpwnam(PKI_USER)
+ os.chown(publishdir, 0, pent.pw_gid)
+
+ ipaservices.restore_context(publishdir)
+
+ return publishdir
+
def __enable_crl_publish(self):
"""
Enable file-based CRL publishing and disable LDAP publishing.
- http://www.redhat.com/docs/manuals/cert-system/8.0/admin/html/Setting_up_Publishing.html
+ https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Certificate_System/8.0/html/Admin_Guide/Setting_up_Publishing.html
"""
caconfig = self.dogtag_constants.CS_CFG_PATH
- publishdir = self.dogtag_constants.CRL_PUBLISH_PATH
- os.mkdir(publishdir)
- os.chmod(publishdir, 0755)
- pent = pwd.getpwnam(PKI_USER)
- os.chown(publishdir, pent.pw_uid, pent.pw_gid)
+ publishdir = self.prepare_crl_publish_dir()
# Enable file publishing, disable LDAP
installutils.set_directive(caconfig, 'ca.publish.enable', 'true', quotes=False, separator='=')
@@ -1211,8 +1238,6 @@ class CAInstance(service.Service):
'https://%s/ipa/crl/MasterCRL.bin' % ipautil.format_netloc(self.fqdn),
quotes=False, separator='=')
- ipaservices.restore_context(publishdir)
-
def __set_subject_in_config(self):
# dogtag ships with an IPA-specific profile that forces a subject
# format. We need to update that template with our base subject
@@ -1249,6 +1274,12 @@ class CAInstance(service.Service):
installutils.remove_file("/var/lib/certmonger/cas/ca_renewal")
+ # remove CRL files
+ root_logger.info("Remove old CRL files")
+ for f in get_crl_files():
+ root_logger.debug("Remove %s", f)
+ installutils.remove_file(f)
+
def publish_ca_cert(self, location):
args = ["-L", "-n", self.canickname, "-a"]
(cert, err, returncode) = self.__run_certutil(args)
diff --git a/selinux/ipa_dogtag/ipa_dogtag.fc b/selinux/ipa_dogtag/ipa_dogtag.fc
index 08c5f3190..c3b2adb42 100644
--- a/selinux/ipa_dogtag/ipa_dogtag.fc
+++ b/selinux/ipa_dogtag/ipa_dogtag.fc
@@ -1,2 +1 @@
-/var/lib/pki-ca/publish(/.*)? gen_context(system_u:object_r:cert_t,s0)
-/var/lib/pki/pki-tomcat/ca/publish(/.*)? gen_context(system_u:object_r:cert_t,s0)
+/var/lib/ipa/pki-ca/publish(/.*)? gen_context(system_u:object_r:cert_t,s0)