Allow ipaapi user to access SSSD's info pipe

For smart card authentication, ipaapi must be able to access to sss-ifp.
During installation and upgrade, the ipaapi user is now added to
[ifp]allowed_uids.

The commit also fixes two related issues:

* The server upgrade code now enables ifp service in sssd.conf. The
  existing code modified sssd.conf but never wrote the changes to disk.
* sssd_enable_service() no longer fails after it has detected an
  unrecognized service.

Fixes: https://pagure.io/freeipa/issue/7751
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
Christian Heimes
2018-11-06 13:57:14 +01:00
parent 324da5c379
commit 8b0f3595fd
3 changed files with 83 additions and 16 deletions

View File

@@ -33,6 +33,7 @@ from configparser import RawConfigParser
from urllib.parse import urlparse, urlunparse
from ipalib import api, errors, x509
from ipalib.constants import IPAAPI_USER
from ipalib.install import certmonger, certstore, service, sysrestore
from ipalib.install import hostname as hostname_
from ipalib.install.kinit import kinit_keytab, kinit_password
@@ -912,7 +913,7 @@ def configure_sssd_conf(
domain = sssdconfig.new_domain(cli_domain)
if options.on_master:
sssd_enable_service(sssdconfig, 'ifp')
sssd_enable_ifp(sssdconfig)
if (
(options.conf_ssh and os.path.isfile(paths.SSH_CONFIG)) or
@@ -1016,21 +1017,47 @@ def configure_sssd_conf(
return 0
def sssd_enable_service(sssdconfig, service):
def sssd_enable_service(sssdconfig, name):
try:
sssdconfig.new_service(service)
sssdconfig.new_service(name)
except SSSDConfig.ServiceAlreadyExists:
pass
except SSSDConfig.ServiceNotRecognizedError:
logger.error(
"Unable to activate the %s service in SSSD config.", service)
"Unable to activate the '%s' service in SSSD config.", name)
logger.info(
"Please make sure you have SSSD built with %s support "
"installed.", service)
"installed.", name)
logger.info(
"Configure %s support manually in /etc/sssd/sssd.conf.", service)
"Configure %s support manually in /etc/sssd/sssd.conf.", name)
return None
sssdconfig.activate_service(service)
sssdconfig.activate_service(name)
return sssdconfig.get_service(name)
def sssd_enable_ifp(sssdconfig):
"""Enable and configure libsss_simpleifp plugin
"""
service = sssd_enable_service(sssdconfig, 'ifp')
if service is None:
# unrecognized service
return
try:
uids = service.get_option('allowed_uids')
except SSSDConfig.NoOptionError:
uids = set()
else:
uids = {s.strip() for s in uids.split(',') if s.strip()}
# SSSD supports numeric and string UIDs
# ensure that root is allowed to access IFP, might be 0 or root
if uids.isdisjoint({'0', 'root'}):
uids.add('root')
# allow IPA API to access IFP
uids.add(IPAAPI_USER)
service.set_option('allowed_uids', ', '.join(sorted(uids)))
sssdconfig.save_service(service)
def change_ssh_config(filename, changes, sections):

View File

@@ -23,7 +23,7 @@ import SSSDConfig
import ipalib.util
import ipalib.errors
from ipaclient.install import timeconf
from ipaclient.install.client import sssd_enable_service
from ipaclient.install.client import sssd_enable_ifp
from ipaplatform import services
from ipaplatform.tasks import tasks
from ipapython import ipautil, version
@@ -1408,6 +1408,22 @@ def set_sssd_domain_option(option, value):
sssdconfig.write(paths.SSSD_CONF)
def sssd_update():
sssdconfig = SSSDConfig.SSSDConfig()
sssdconfig.import_config()
# upgrade domain
domain = sssdconfig.get_domain(str(api.env.domain))
domain.set_option('ipa_server_mode', 'True')
domain.set_option('ipa_server', api.env.host)
sssdconfig.save_domain(domain)
# enable and configure IFP plugin
sssd_enable_ifp(sssdconfig)
# write config and restart service
sssdconfig.write(paths.SSSD_CONF)
sssd = services.service('sssd', api)
sssd.restart()
def remove_ds_ra_cert(subject_base):
logger.info('[Removing RA cert from DS NSS database]')
@@ -2017,15 +2033,8 @@ def upgrade_configuration():
cainstance.ensure_ipa_authority_entry()
migrate_to_authselect()
set_sssd_domain_option('ipa_server_mode', 'True')
set_sssd_domain_option('ipa_server', api.env.host)
sssdconfig = SSSDConfig.SSSDConfig()
sssdconfig.import_config()
sssd_enable_service(sssdconfig, 'ifp')
sssd = services.service('sssd', api)
sssd.restart()
sssd_update()
krb = krbinstance.KrbInstance(fstore)
krb.fqdn = fqdn

View File

@@ -20,6 +20,8 @@ import pytest
from cryptography.hazmat.backends import default_backend
from cryptography import x509
from ipalib.constants import IPAAPI_USER
from ipaplatform.paths import paths
from ipatests.test_integration.base import IntegrationTest
@@ -28,6 +30,7 @@ from ipatests.create_external_ca import ExternalCA
logger = logging.getLogger(__name__)
class TestIPACommand(IntegrationTest):
"""
A lot of commands can be executed against a single IPA installation
@@ -429,3 +432,31 @@ class TestIPACommand(IntegrationTest):
x509.load_pem_x509_certificate(data, backend=default_backend())
self.master.run_command(['rm', '-f', filename])
def test_sssd_ifp_access_ipaapi(self):
# check that ipaapi is allowed to access sssd-ifp for smartcard auth
# https://pagure.io/freeipa/issue/7751
username = 'admin'
# get UID for user
result = self.master.run_command(['ipa', 'user-show', username])
mo = re.search(r'UID: (\d+)', result.stdout_text)
assert mo is not None, result.stdout_text
uid = mo.group(1)
cmd = [
'dbus-send',
'--print-reply', '--system',
'--dest=org.freedesktop.sssd.infopipe',
'/org/freedesktop/sssd/infopipe/Users',
'org.freedesktop.sssd.infopipe.Users.FindByName',
'string:{}'.format(username)
]
# test IFP as root
result = self.master.run_command(cmd)
assert uid in result.stdout_text
# test IFP as ipaapi
result = self.master.run_command(
['sudo', '-u', IPAAPI_USER, '--'] + cmd
)
assert uid in result.stdout_text