URL: https://github.com/freeipa/freeipa/pull/2528
Author: tiran
 Title: #2528: [Backport][ipa-4-6] Allow ipaapi user to access SSSD's info pipe
Action: opened

PR body:
"""
Manual backport of PR #2515 

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 <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/2528/head:pr2528
git checkout pr2528
From fc1d73918f5519c34b95aab10e5ae5e2ae0221d0 Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 6 Nov 2018 13:57:14 +0100
Subject: [PATCH] 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 <chei...@redhat.com>
---
 ipaclient/install/client.py                | 41 ++++++++++++++++++----
 ipaserver/install/server/upgrade.py        | 31 +++++++++++-----
 ipatests/test_integration/test_commands.py | 31 ++++++++++++++++
 3 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index 234d4df568..80b572ce9b 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -33,6 +33,7 @@
 # pylint: enable=import-error
 
 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
@@ -866,7 +867,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
@@ -970,21 +971,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):
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 0cc25fa6e5..00ad5a6a6d 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -22,7 +22,12 @@
 import SSSDConfig
 import ipalib.util
 import ipalib.errors
+<<<<<<< HEAD
 from ipaclient.install.client import sssd_enable_service
+=======
+from ipaclient.install import timeconf
+from ipaclient.install.client import sssd_enable_ifp
+>>>>>>> 11367e104... Allow ipaapi user to access SSSD's info pipe
 from ipaplatform import services
 from ipaplatform.tasks import tasks
 from ipapython import ipautil, version, certdb
@@ -1393,6 +1398,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]')
 
@@ -1964,15 +1985,7 @@ def upgrade_configuration():
         ca.setup_lightweight_ca_key_retrieval()
         cainstance.ensure_ipa_authority_entry()
 
-    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
diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py
index 565194e6b4..5b7c138dd1 100644
--- a/ipatests/test_integration/test_commands.py
+++ b/ipatests/test_integration/test_commands.py
@@ -20,6 +20,8 @@
 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 @@
 
 logger = logging.getLogger(__name__)
 
+
 class TestIPACommand(IntegrationTest):
     """
     A lot of commands can be executed against a single IPA installation
@@ -401,3 +404,31 @@ def test_certificate_out_write_to_file(self):
             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
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org

Reply via email to