Generate tmpfiles config at install time

We do not want to generate runtime directories just because the packages
are installed, but only if the server is actually setup and run. Also this
will be needed later because we will create a user at install time and some
tmpfiles will need to be owned by this user.
As we are changing this code also rationalize the directory structure and
move it from the http rundir to the ipa specific rundir.

https://fedorahosted.org/freeipa/ticket/5959

Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Simo Sorce 2016-12-01 11:37:20 -05:00 committed by Jan Cholasta
parent c894ebefc5
commit 38c66896de
17 changed files with 78 additions and 67 deletions

View File

@ -523,7 +523,6 @@ AC_CONFIG_FILES([
daemons/ipa-slapi-plugins/ipa-range-check/Makefile
daemons/ipa-slapi-plugins/topology/Makefile
init/systemd/Makefile
init/tmpfilesd/Makefile
init/Makefile
install/Makefile
install/certmonger/Makefile

View File

@ -1189,12 +1189,6 @@ fi
%config(noreplace) %{_sysconfdir}/sysconfig/ipa-dnskeysyncd
%config(noreplace) %{_sysconfdir}/sysconfig/ipa-ods-exporter
%config(noreplace) %{_sysconfdir}/ipa/kdcproxy/kdcproxy.conf
%dir %attr(0700,root,root) %{_localstatedir}/run/ipa/
%dir %attr(0700,apache,apache) %{_localstatedir}/run/httpd/ipa/
%dir %attr(0700,apache,apache) %{_localstatedir}/run/httpd/ipa/clientcaches/
%dir %attr(0700,apache,apache) %{_localstatedir}/run/httpd/ipa/krbcache/
# NOTE: systemd specific section
%{_tmpfilesdir}/ipa.conf
%attr(644,root,root) %{_unitdir}/ipa-custodia.service
%ghost %attr(644,root,root) %{etc_systemd_dir}/httpd.d/ipa.conf
# END
@ -1204,6 +1198,7 @@ fi
%{_usr}/share/ipa/*.ldif
%{_usr}/share/ipa/*.uldif
%{_usr}/share/ipa/*.template
%{_usr}/share/ipa/ipa.conf.tmpfiles
%dir %{_usr}/share/ipa/advise
%dir %{_usr}/share/ipa/advise/legacy
%{_usr}/share/ipa/advise/legacy/*.template

View File

@ -2,7 +2,7 @@
#
AUTOMAKE_OPTIONS = 1.7
SUBDIRS = systemd tmpfilesd
SUBDIRS = systemd
dist_sysconfenv_DATA = \
ipa-dnskeysyncd \

View File

@ -1,20 +0,0 @@
dist_noinst_DATA = \
ipa.conf.in
systemdtmpfiles_DATA = \
ipa.conf
CLEANFILES = $(systemdtmpfiles_DATA)
%: %.in Makefile
sed -e 's|@localstatedir[@]|$(localstatedir)|g' '$(srcdir)/$@.in' >$@
# create empty directories as needed
# DESTDIR might not be set, in that case default to system root
DESTDIR ?= /
install-data-hook:
for conf in $(systemdtmpfiles_DATA); do \
systemd-tmpfiles --remove --create --boot \
--root $(DESTDIR) \
$(DESTDIR)$(systemdtmpfilesdir)/$${conf} || :; \
done

View File

@ -1,4 +0,0 @@
d @localstatedir@/run/ipa 0700 root root
d @localstatedir@/run/httpd/ipa 0700 apache apache
d @localstatedir@/run/httpd/ipa/clientcaches 0700 apache apache
d @localstatedir@/run/httpd/ipa/krbcache 0700 apache apache

View File

@ -71,7 +71,7 @@ WSGIScriptReloading Off
GssapiCredStore keytab:/etc/httpd/conf/ipa.keytab
GssapiCredStore client_keytab:/etc/httpd/conf/ipa.keytab
GssapiDelegCcacheDir /var/run/httpd/ipa/clientcaches
GssapiDelegCcacheDir /var/run/ipa/ccaches
GssapiUseS4U2Proxy on
GssapiAllowedMech krb5
Require valid-user

View File

@ -88,6 +88,7 @@ dist_app_DATA = \
kdcproxy-disable.uldif \
ipa-httpd.conf.template \
gssapi.login \
ipa.conf.tmpfiles \
$(NULL)
kdcproxyconfdir = $(IPA_SYSCONF_DIR)/kdcproxy

View File

@ -0,0 +1,2 @@
d /var/run/ipa 0700 root root
d /var/run/ipa/ccaches 0700 apache apache

View File

@ -130,6 +130,7 @@ class BasePathNamespace(object):
SYSTEMD_SSSD_SERVICE = "/etc/systemd/system/multi-user.target.wants/sssd.service"
SYSTEMD_PKI_TOMCAT_SERVICE = "/etc/systemd/system/pki-tomcatd.target.wants/pki-tomcatd@pki-tomcat.service"
ETC_TMPFILESD_DIRSRV = "/etc/tmpfiles.d/dirsrv-%s.conf"
ETC_TMPFILESD_IPA = "/etc/tmpfiles.d/ipa.conf"
DNSSEC_TRUSTED_KEY = "/etc/trusted-key.key"
HOME_DIR = "/home"
PROC_FIPS_ENABLED = "/proc/sys/crypto/fips_enabled"
@ -325,10 +326,10 @@ class BasePathNamespace(object):
OPENDNSSEC_KASP_DB = "/var/opendnssec/kasp.db"
IPA_ODS_EXPORTER_CCACHE = "/var/opendnssec/tmp/ipa-ods-exporter.ccache"
VAR_RUN_DIRSRV_DIR = "/var/run/dirsrv"
KRB5CC_HTTPD = "/var/run/httpd/ipa/krbcache/krb5ccache"
IPA_CCACHES = "/var/run/ipa/ccaches"
KRB5CC_HTTPD = "/var/run/ipa/ccaches/http.ccache"
IPA_RENEWAL_LOCK = "/var/run/ipa/renewal.lock"
SVC_LIST_FILE = "/var/run/ipa/services.list"
IPA_HTTPD_DIR = "/var/run/httpd"
KRB5CC_SAMBA = "/var/run/samba/krb5cc_samba"
SLAPD_INSTANCE_SOCKET_TEMPLATE = "/var/run/slapd-%s.socket"
ALL_SLAPD_INSTANCE_SOCKETS = "/var/run/slapd-*.socket"

View File

@ -243,6 +243,14 @@ class BaseTaskNamespace(object):
"""
raise NotImplementedError()
def configure_tmpfiles(self):
"""Configure tmpfiles to be created at boot"""
raise NotImplementedError()
def create_tmpfiles_dirs(self):
"""Create run dirs for the install phase"""
raise NotImplementedError()
def configure_httpd_service_ipa_conf(self):
"""Configure httpd service to work with IPA"""
raise NotImplementedError()

View File

@ -26,6 +26,8 @@ system tasks.
from __future__ import print_function
import os
import pwd
import shutil
import socket
import base64
import traceback
@ -497,4 +499,24 @@ class RedHatTaskNamespace(BaseTaskNamespace):
pass
return False
def _create_tmpfiles_dir(self, name, mode, uid, gid):
if not os.path.exists(name):
os.mkdir(name)
os.chmod(name, mode)
os.chown(name, uid, gid)
def create_tmpfiles_dirs(self):
parent = os.path.dirname(paths.IPA_CCACHES)
pent = pwd.getpwnam(constants.HTTPD_USER)
self._create_tmpfiles_dir(parent, 0o711, 0, 0)
self._create_tmpfiles_dir(paths.IPA_CCACHES, 0o770,
pent.pw_uid, pent.pw_gid)
def configure_tmpfiles(self):
shutil.copy(
os.path.join(paths.USR_SHARE_IPA_DIR, 'ipa.conf.tmpfiles'),
paths.ETC_TMPFILESD_IPA
)
tasks = RedHatTaskNamespace()

View File

@ -51,7 +51,6 @@ from cryptography.hazmat.primitives.ciphers import Cipher, algorithms
from cryptography.hazmat.backends import default_backend
import ldap as _ldap
from ipapython import ipaldap
from ipaserver.session import krbccache_dir, krbccache_prefix
from dns import resolver, rdatatype
from dns.exception import DNSException
import pysss_nss_idmap
@ -639,8 +638,8 @@ class DomainValidator(object):
Initializes ccache with http service credentials.
Applies session code defaults for ccache directory and naming prefix.
Session code uses krbccache_prefix+<pid>, we use
krbccache_prefix+<TD>+<domain netbios name> so there is no clash.
Session code uses kinit_+<pid>, we use
kinit_+<TD>+<domain netbios name> so there is no clash.
Returns tuple (ccache path, principal) where (None, None) signifes an
error on ccache initialization
@ -648,8 +647,8 @@ class DomainValidator(object):
domain_suffix = domain.replace('.', '-')
ccache_name = "%sTD%s" % (krbccache_prefix, domain_suffix)
ccache_path = os.path.join(krbccache_dir, ccache_name)
ccache_name = "kinit_TD%s" % (domain_suffix)
ccache_path = os.path.join(paths.IPA_CCACHES, ccache_name)
realm = api.env.realm
hostname = api.env.host
@ -683,8 +682,8 @@ class DomainValidator(object):
Initializes ccache with http service credentials.
Applies session code defaults for ccache directory and naming prefix.
Session code uses krbccache_prefix+<pid>, we use
krbccache_prefix+<TD>+<domain netbios name> so there is no clash.
Session code uses kinit_+<pid>, we use
kinit_+<TD>+<domain netbios name> so there is no clash.
Returns tuple (ccache path, principal) where (None, None) signifes an
error on ccache initialization
@ -695,8 +694,8 @@ class DomainValidator(object):
domain_suffix = domain.replace('.', '-')
ccache_name = "%sTDA%s" % (krbccache_prefix, domain_suffix)
ccache_path = os.path.join(krbccache_dir, ccache_name)
ccache_name = "kinit_TDA%s" % (domain_suffix)
ccache_path = os.path.join(paths.IPA_CCACHES, ccache_name)
(principal, password) = self._admin_creds.split('%', 1)

View File

@ -709,6 +709,9 @@ def install(installer):
if installer._update_hosts_file:
update_hosts_file(ip_addresses, host_name, fstore)
# Make sure tmpfiles dir exist before installing components
tasks.create_tmpfiles_dirs()
http_instance = httpinstance.HTTPInstance()
http_instance.create_cert_db()
@ -878,6 +881,9 @@ def install(installer):
except Exception:
raise ScriptError("Configuration of client side components failed!")
# Make sure the files we crated in /var/run are recreated at startup
tasks.configure_tmpfiles()
# Everything installed properly, activate ipa service.
services.knownservices.ipa.enable()

View File

@ -1301,6 +1301,9 @@ def install(installer):
conn = remote_api.Backend.ldap2
ccache = os.environ['KRB5CCNAME']
# Make sure tmpfiles dir exist before installing components
tasks.create_tmpfiles_dirs()
if promote:
if installer._add_to_ipaservers:
try:

View File

@ -1795,6 +1795,10 @@ def upgrade_check(options):
def upgrade():
# Do this early so that any code depending on these dirs will not fail
tasks.create_tmpfiles_dirs()
tasks.configure_tmpfiles()
realm = api.env.realm
schema_files = [os.path.join(paths.USR_SHARE_IPA_DIR, f) for f
in dsinstance.ALL_SCHEMA_FILES]

View File

@ -53,9 +53,6 @@ from ipalib.rpc import (xml_dumps, xml_loads,
from ipalib.util import normalize_name
from ipapython.dn import DN
from ipaserver.plugins.ldap2 import ldap2
from ipaserver.session import (
get_ipa_ccache_name,
krbccache_dir, krbccache_prefix)
from ipalib.backend import Backend
from ipalib.krb_utils import (
krb5_format_principal_name,
@ -913,7 +910,13 @@ class login_password(Backend, KerberosSession):
return self.bad_request(environ, start_response, "no password specified")
# Get the ccache we'll use and attempt to get credentials in it with user,password
ipa_ccache_name = get_ipa_ccache_name()
ipa_ccache_name = os.path.join(paths.IPA_CCACHES,
'kinit_{}'.format(os.getpid()))
try:
# try to remove in case an old file was there
os.unlink(ipa_ccache_name)
except OSError:
pass
try:
self.kinit(user, self.api.env.realm, password, ipa_ccache_name)
except PasswordExpired as e:
@ -931,15 +934,23 @@ class login_password(Backend, KerberosSession):
str(e),
'user-locked')
return self.finalize_kerberos_acquisition('login_password', ipa_ccache_name, environ, start_response)
result = self.finalize_kerberos_acquisition('login_password',
ipa_ccache_name, environ,
start_response)
try:
# Try not to litter the filesystem with unused TGTs
os.unlink(ipa_ccache_name)
except OSError:
pass
return result
def kinit(self, user, realm, password, ccache_name):
# get http service ccache as an armor for FAST to enable OTP authentication
armor_principal = str(krb5_format_service_principal_name(
'HTTP', self.api.env.host, realm))
keytab = paths.IPA_KEYTAB
armor_name = "%sA_%s" % (krbccache_prefix, user)
armor_path = os.path.join(krbccache_dir, armor_name)
armor_path = os.path.join(paths.IPA_CCACHES,
"armor_{}".format(os.getpid()))
self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s',
armor_principal, keytab, armor_path)

View File

@ -21,23 +21,7 @@ import os
from ipalib.request import context
from ipalib.krb_utils import (
krb5_parse_ccache,
krb5_unparse_ccache
)
from ipaplatform.paths import paths
krbccache_dir = paths.IPA_HTTPD_DIR
krbccache_prefix = 'krbcc_'
def get_ipa_ccache_name(scheme='FILE'):
if scheme == 'FILE':
name = os.path.join(krbccache_dir, '%s%s' % (krbccache_prefix, os.getpid()))
else:
raise ValueError('ccache scheme "%s" unsupported', scheme)
ccache_name = krb5_unparse_ccache(scheme, name)
return ccache_name
def logout(ccache_name=None):