Add a new user to run the framework code

Add the apache user the ipawebui group.
Make the ccaches directory owned by the ipawebui group and make
mod_auth_gssapi write the ccache files as r/w by the apache user and
the ipawebui group.
Fix tmpfiles creation ownership and permissions to allow the user to
access ccaches files.
The webui framework now works as a separate user than apache, so the certs
used to access the dogtag instance need to be usable by this new user as well.
Both apache and the webui user are in the ipawebui group, so use that.

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-08-16 09:03:19 -04:00 committed by Jan Cholasta
parent c2b1b2a362
commit 4fd89833ee
18 changed files with 73 additions and 26 deletions

View File

@ -1,5 +1,5 @@
#
# VERSION 22 - DO NOT REMOVE THIS LINE
# VERSION 23 - DO NOT REMOVE THIS LINE
#
# This file may be overwritten on upgrades.
#
@ -42,7 +42,7 @@ WSGISocketPrefix /run/httpd/wsgi
# Configure mod_wsgi handler for /ipa
WSGIDaemonProcess ipa processes=2 threads=1 maximum-requests=500 \
display-name=%{GROUP} socket-timeout=2147483647
user=ipaapi group=ipaapi display-name=%{GROUP} socket-timeout=2147483647
WSGIImportScript /usr/share/ipa/wsgi.py process-group=ipa application-group=ipa
WSGIScriptAlias /ipa /usr/share/ipa/wsgi.py
WSGIScriptReloading Off
@ -70,6 +70,7 @@ WSGIScriptReloading Off
GssapiSessionKey file:/etc/httpd/alias/ipasession.key
GssapiDelegCcacheDir /var/run/ipa/ccaches
GssapiDelegCcachePerms mode:0660 gid:ipaapi
GssapiUseS4U2Proxy on
GssapiAllowedMech krb5
Require valid-user

View File

@ -30,7 +30,7 @@
send_member="Get"/>
</policy>
<policy user="apache">
<policy user="ipaapi">
<allow send_destination="com.redhat.idm.trust"
send_path="/"
send_interface="com.redhat.idm.trust"

View File

@ -10,7 +10,7 @@
<allow send_destination="org.freeipa.server" send_interface="org.freeipa.server"/>
</policy>
<policy user="apache">
<policy user="ipaapi">
<allow send_destination="org.freeipa.server" send_interface="org.freeipa.server"/>
</policy>

View File

@ -2,7 +2,7 @@
<oddjobconfig>
<service name="org.freeipa.server">
<allow user="root"/>
<allow user="apache"/>
<allow user="ipaapi"/>
<object name="/">
<interface name="org.freeipa.server">
<method name="conncheck">

View File

@ -2,7 +2,7 @@
<oddjobconfig>
<service name="com.redhat.idm.trust">
<allow user="root"/>
<allow user="apache"/>
<allow user="ipaapi"/>
<object name="/">
<interface name="org.freedesktop.DBus.Introspectable">
<allow min_uid="0" max_uid="0"/>

View File

@ -6,3 +6,11 @@
allow_protocol_transition = true
cred_usage = both
euid = $HTTPD_USER
[service/ipa-api]
mechs = krb5
cred_store = keytab:$HTTP_KEYTAB
cred_store = client_keytab:$HTTP_KEYTAB
allow_constrained_delegation = true
cred_usage = initiate
euid = $IPAAPI_USER

View File

@ -1,2 +1,2 @@
d /var/run/ipa 0700 root root
d /var/run/ipa/ccaches 0700 apache apache
d /var/run/ipa 0711 root root
d /var/run/ipa/ccaches 0770 ipaapi ipaapi

View File

@ -279,3 +279,7 @@ PATTERN_GROUPUSER_NAME = '^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[a-zA-Z0-9_.$-]?$'
# Kerberos Anonymous principal name
ANON_USER = 'WELLKNOWN/ANONYMOUS'
# IPA API Framework user
IPAAPI_USER = 'ipaapi'
IPAAPI_GROUP = 'ipaapi'

View File

@ -203,6 +203,7 @@ class BasePathNamespace(object):
DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
GETSEBOOL = "/usr/sbin/getsebool"
GROUPADD = "/usr/sbin/groupadd"
USERMOD = "/usr/sbin/usermod"
HTTPD = "/usr/sbin/httpd"
IPA_CLIENT_INSTALL = "/usr/sbin/ipa-client-install"
IPA_DNS_INSTALL = "/usr/sbin/ipa-dns-install"

View File

@ -181,7 +181,9 @@ class BaseTaskNamespace(object):
raise NotImplementedError()
def create_system_user(self, name, group, homedir, shell, uid=None, gid=None, comment=None, create_homedir=False):
def create_system_user(self, name, group, homedir, shell,
uid=None, gid=None, comment=None,
create_homedir=False, groups=None):
"""Create a system user with a corresponding group"""
try:
grp.getgrnam(group)
@ -218,6 +220,8 @@ class BaseTaskNamespace(object):
args += ['-m']
else:
args += ['-M']
if groups is not None:
args += ['-G', groups.join(',')]
try:
ipautil.run(args)
log.debug('Done adding user')
@ -261,3 +265,12 @@ class BaseTaskNamespace(object):
def is_fips_enabled(self):
return False
def add_user_to_group(self, user, group):
log.debug('Adding user %s to group %s', user, group)
args = [paths.USERMOD, '-a', '-G', group, user]
try:
ipautil.run(args)
log.debug('Done adding user to group')
except ipautil.CalledProcessError as e:
log.debug('Failed to add user to group: %s', e)

View File

@ -51,6 +51,8 @@ from ipaplatform.paths import paths
from ipaplatform.redhat.authconfig import RedHatAuthConfig
from ipaplatform.base.tasks import BaseTaskNamespace
from ipalib.constants import IPAAPI_USER
_ffi = FFI()
_ffi.cdef("""
int rpmvercmp (const char *a, const char *b);
@ -411,7 +413,9 @@ class RedHatTaskNamespace(BaseTaskNamespace):
return True
def create_system_user(self, name, group, homedir, shell, uid=None, gid=None, comment=None, create_homedir=False):
def create_system_user(self, name, group, homedir, shell,
uid=None, gid=None, comment=None,
create_homedir=False, groups=None):
"""
Create a system user with a corresponding group
@ -431,8 +435,9 @@ class RedHatTaskNamespace(BaseTaskNamespace):
if comment is None:
comment = 'DS System User'
super(RedHatTaskNamespace, self).create_system_user(name, group,
homedir, shell, uid, gid, comment, create_homedir)
super(RedHatTaskNamespace, self).create_system_user(
name, group, homedir, shell, uid, gid, comment, create_homedir,
groups)
def parse_ipa_version(self, version):
"""
@ -467,7 +472,8 @@ class RedHatTaskNamespace(BaseTaskNamespace):
dict(
HTTP_KEYTAB=paths.HTTP_KEYTAB,
HTTP_CCACHE=paths.HTTP_CCACHE,
HTTPD_USER=constants.HTTPD_USER
HTTPD_USER=constants.HTTPD_USER,
IPAAPI_USER=IPAAPI_USER,
)
)
@ -520,7 +526,7 @@ class RedHatTaskNamespace(BaseTaskNamespace):
def create_tmpfiles_dirs(self):
parent = os.path.dirname(paths.IPA_CCACHES)
pent = pwd.getpwnam(constants.HTTPD_USER)
pent = pwd.getpwnam(IPAAPI_USER)
self._create_tmpfiles_dir(parent, 0o711, 0, 0)
self._create_tmpfiles_dir(paths.IPA_CCACHES, 0o770,
pent.pw_uid, pent.pw_gid)

View File

@ -31,6 +31,7 @@ import pki.system
from ipalib import api, errors
from ipalib.constants import IPAAPI_USER
from ipalib.install import certmonger
from ipaplatform import services
from ipaplatform.constants import constants
@ -44,8 +45,6 @@ from ipaserver.install import replication
from ipaserver.install.installutils import stopped_service
from ipapython.ipa_log_manager import log_mgr
HTTPD_USER = constants.HTTPD_USER
def get_security_domain():
"""
@ -87,7 +86,7 @@ def export_kra_agent_pem():
"--client-cert", filename]
ipautil.run(args)
pent = pwd.getpwnam(HTTPD_USER)
pent = pwd.getpwnam(IPAAPI_USER)
os.chown(filename, 0, pent.pw_gid)
os.chmod(filename, 0o440)

View File

@ -30,6 +30,7 @@ import locale
import six
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
from ipalib.install import certmonger
from ipaserver.install import service
from ipaserver.install import certs
@ -317,8 +318,7 @@ class HTTPInstance(service.Service):
nssdb = certdb.NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
nssdb.create_db(user="root", group=constants.HTTPD_GROUP, backup=True)
nssdb = certdb.NSSDatabase(nssdir=paths.IPA_RADB_DIR)
nssdb.create_db(user=constants.HTTPD_USER, group=constants.HTTPD_GROUP,
mode=0o751, backup=True)
nssdb.create_db(user=IPAAPI_USER, group=IPAAPI_GROUP, backup=True)
def request_anon_keytab(self):
parent = os.path.dirname(paths.ANON_KEYTAB)
@ -326,7 +326,7 @@ class HTTPInstance(service.Service):
os.makedirs(parent, 0o755)
self.run_getkeytab(self.api.env.ldap_uri, paths.ANON_KEYTAB, ANON_USER)
pent = pwd.getpwnam(self.service_user)
pent = pwd.getpwnam(IPAAPI_USER)
os.chmod(parent, 0o700)
os.chown(parent, pent.pw_uid, pent.pw_gid)
os.chown(paths.ANON_KEYTAB, pent.pw_uid, pent.pw_gid)

View File

@ -44,6 +44,7 @@ import six
from six.moves.configparser import SafeConfigParser, NoOptionError
# pylint: enable=import-error
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
from ipalib.install import sysrestore
from ipalib.install.kinit import kinit_password
import ipaplatform
@ -55,6 +56,7 @@ from ipalib import api, errors, x509
from ipapython.dn import DN
from ipaserver.install import certs, service, sysupgrade
from ipaplatform import services
from ipaplatform.constants import constants
from ipaplatform.paths import paths
from ipaplatform.tasks import tasks
@ -1513,3 +1515,14 @@ def default_subject_base(realm_name):
def default_ca_subject_dn(subject_base):
return DN(('CN', 'Certificate Authority'), subject_base)
def create_ipaapi_user():
"""Create IPA API user/group if it doesn't exist yet."""
tasks.create_system_user(
name=IPAAPI_USER,
group=IPAAPI_GROUP,
homedir=paths.VAR_LIB,
shell=paths.NOLOGIN
)
tasks.add_user_to_group(constants.HTTPD_USER, IPAAPI_GROUP)

View File

@ -7,8 +7,8 @@ import os
from ipalib import Registry
from ipalib import Updater
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
from ipalib.install import certmonger
from ipaplatform.constants import constants
from ipaplatform.paths import paths
from ipapython import certdb
@ -37,9 +37,7 @@ class update_ra_cert_store(Updater):
return False, []
else:
# Create the DB
newdb.create_db(user=constants.HTTPD_USER,
group=constants.HTTPD_GROUP,
mode=0o751, backup=True)
newdb.create_db(user=IPAAPI_USER, group=IPAAPI_GROUP, backup=True)
# Import cert chain (ignore errors, as certs may already be imported)
certlist = olddb.list_certs()

View File

@ -38,7 +38,7 @@ from ipaserver.install import (
from ipaserver.install.installutils import (
IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
is_ipa_configured, load_pkcs12, read_password, verify_fqdn,
update_hosts_file)
update_hosts_file, create_ipaapi_user)
if six.PY3:
unicode = str
@ -710,6 +710,7 @@ def install(installer):
update_hosts_file(ip_addresses, host_name, fstore)
# Make sure tmpfiles dir exist before installing components
create_ipaapi_user()
tasks.create_tmpfiles_dirs()
# create NSS Databases

View File

@ -40,7 +40,8 @@ from ipaserver.install import (
installutils, kra, krbinstance,
ntpinstance, otpdinstance, custodiainstance, service)
from ipaserver.install.installutils import (
create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured)
create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured,
create_ipaapi_user)
from ipaserver.install.replication import (
ReplicationManager, replica_conn_check)
import SSSDConfig
@ -1305,6 +1306,7 @@ def install(installer):
ccache = os.environ['KRB5CCNAME']
# Make sure tmpfiles dir exist before installing components
create_ipaapi_user()
tasks.create_tmpfiles_dirs()
if promote:

View File

@ -1807,6 +1807,7 @@ def upgrade_check(options):
def upgrade():
# Do this early so that any code depending on these dirs will not fail
installutils.create_ipaapi_user()
tasks.create_tmpfiles_dirs()
tasks.configure_tmpfiles()