6d47df
From aaf938307acbe987f5e1effc2392894c22235013 Mon Sep 17 00:00:00 2001
6d47df
From: Christian Heimes <cheimes@redhat.com>
6d47df
Date: Fri, 11 Jan 2019 11:18:05 +0100
6d47df
Subject: [PATCH] Create systemd-user HBAC service and rule
6d47df
6d47df
authselect changed pam_systemd session from optional to required. When
6d47df
the HBAC rule allow_all is disabled and replaced with more fine grained
6d47df
rules, loginsi now to fail, because systemd's user@.service is able to
6d47df
create a systemd session.
6d47df
6d47df
Add systemd-user HBAC service and a HBAC rule that allows systemd-user
6d47df
to run on all hosts for all users by default. ipa-server-upgrade creates
6d47df
the service and rule, too. In case the service already exists, no
6d47df
attempt is made to create the rule. This allows admins to delete the
6d47df
rule permanently.
6d47df
6d47df
See: https://bugzilla.redhat.com/show_bug.cgi?id=1643928
6d47df
Fixes: https://pagure.io/freeipa/issue/7831
6d47df
Signed-off-by: Christian Heimes <cheimes@redhat.com>
6d47df
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
6d47df
---
6d47df
 install/share/bootstrap-template.ldif      |  8 +++
6d47df
 install/share/default-hbac.ldif            | 13 +++++
6d47df
 ipaserver/install/server/upgrade.py        | 36 +++++++++++++
6d47df
 ipatests/test_integration/test_commands.py | 59 ++++++++++++++++++++++
6d47df
 4 files changed, 116 insertions(+)
6d47df
6d47df
diff --git a/install/share/bootstrap-template.ldif b/install/share/bootstrap-template.ldif
6d47df
index d48c4fafc..6cd17e37e 100644
6d47df
--- a/install/share/bootstrap-template.ldif
6d47df
+++ b/install/share/bootstrap-template.ldif
6d47df
@@ -346,6 +346,14 @@ cn: sudo-i
6d47df
 description: sudo-i
6d47df
 ipauniqueid:autogenerate
6d47df
 
6d47df
+dn: cn=systemd-user,cn=hbacservices,cn=hbac,$SUFFIX
6d47df
+changetype: add
6d47df
+objectclass: ipahbacservice
6d47df
+objectclass: ipaobject
6d47df
+cn: systemd-user
6d47df
+description: pam_systemd and systemd user@.service
6d47df
+ipauniqueid:autogenerate
6d47df
+
6d47df
 dn: cn=gdm,cn=hbacservices,cn=hbac,$SUFFIX
6d47df
 changetype: add
6d47df
 objectclass: ipahbacservice
6d47df
diff --git a/install/share/default-hbac.ldif b/install/share/default-hbac.ldif
6d47df
index 52fd30ec9..8dd90685c 100644
6d47df
--- a/install/share/default-hbac.ldif
6d47df
+++ b/install/share/default-hbac.ldif
6d47df
@@ -12,3 +12,16 @@ ipaenabledflag: TRUE
6d47df
 description: Allow all users to access any host from any host
6d47df
 ipauniqueid: autogenerate
6d47df
 
6d47df
+# default HBAC policy for pam_systemd
6d47df
+dn: ipauniqueid=autogenerate,cn=hbac,$SUFFIX
6d47df
+changetype: add
6d47df
+objectclass: ipaassociation
6d47df
+objectclass: ipahbacrule
6d47df
+cn: allow_systemd-user
6d47df
+accessruletype: allow
6d47df
+usercategory: all
6d47df
+hostcategory: all
6d47df
+servicecategory: systemd-user
6d47df
+ipaenabledflag: TRUE
6d47df
+description: Allow pam_systemd to run user@.service to create a system user session
6d47df
+ipauniqueid: autogenerate
6d47df
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
6d47df
index ae6fcc77e..3869bae3c 100644
6d47df
--- a/ipaserver/install/server/upgrade.py
6d47df
+++ b/ipaserver/install/server/upgrade.py
6d47df
@@ -1735,6 +1735,41 @@ def migrate_to_authselect():
6d47df
     sysupgrade.set_upgrade_state('authcfg', 'migrated_to_authselect', True)
6d47df
 
6d47df
 
6d47df
+def add_systemd_user_hbac():
6d47df
+    logger.info('[Create systemd-user hbac service and rule]')
6d47df
+    rule = 'allow_systemd-user'
6d47df
+    service = 'systemd-user'
6d47df
+    try:
6d47df
+        api.Command.hbacsvc_add(
6d47df
+            service,
6d47df
+            description='pam_systemd and systemd user@.service'
6d47df
+        )
6d47df
+    except ipalib.errors.DuplicateEntry:
6d47df
+        logger.info('hbac service %s already exists', service)
6d47df
+        # Don't create hbac rule when hbacsvc already exists, so the rule
6d47df
+        # does not get re-created after it has been deleted by an admin.
6d47df
+        return
6d47df
+    else:
6d47df
+        logger.info('Created hbacsvc %s', service)
6d47df
+
6d47df
+    try:
6d47df
+        api.Command.hbacrule_add(
6d47df
+            rule,
6d47df
+            description=('Allow pam_systemd to run user@.service to create '
6d47df
+                         'a system user session'),
6d47df
+            usercategory='all',
6d47df
+            hostcategory='all',
6d47df
+        )
6d47df
+    except ipalib.errors.DuplicateEntry:
6d47df
+        logger.info('hbac rule %s already exists', rule)
6d47df
+    else:
6d47df
+        api.Command.hbacrule_add_service(
6d47df
+            rule,
6d47df
+            hbacsvc=(service,)
6d47df
+        )
6d47df
+        logger.info('Created hbac rule %s with hbacsvc=%s', rule, service)
6d47df
+
6d47df
+
6d47df
 def fix_permissions():
6d47df
     """Fix permission of public accessible files and directories
6d47df
 
6d47df
@@ -2050,6 +2085,7 @@ def upgrade_configuration():
6d47df
         cainstance.ensure_ipa_authority_entry()
6d47df
 
6d47df
     migrate_to_authselect()
6d47df
+    add_systemd_user_hbac()
6d47df
 
6d47df
     sssd_update()
6d47df
 
6d47df
diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py
6d47df
index cfb2fa48d..1fb6450a2 100644
6d47df
--- a/ipatests/test_integration/test_commands.py
6d47df
+++ b/ipatests/test_integration/test_commands.py
6d47df
@@ -462,3 +462,62 @@ class TestIPACommand(IntegrationTest):
6d47df
             ['sudo', '-u', IPAAPI_USER, '--'] + cmd
6d47df
         )
6d47df
         assert uid in result.stdout_text
6d47df
+
6d47df
+    def test_hbac_systemd_user(self):
6d47df
+        # https://pagure.io/freeipa/issue/7831
6d47df
+        tasks.kinit_admin(self.master)
6d47df
+        # check for presence
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacrule-show', 'allow_systemd-user']
6d47df
+        )
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacsvc-show', 'systemd-user']
6d47df
+        )
6d47df
+
6d47df
+        # delete both
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacrule-del', 'allow_systemd-user']
6d47df
+        )
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacsvc-del', 'systemd-user']
6d47df
+        )
6d47df
+
6d47df
+        # run upgrade
6d47df
+        result = self.master.run_command(['ipa-server-upgrade'])
6d47df
+        assert 'Created hbacsvc systemd-user' in result.stderr_text
6d47df
+        assert 'Created hbac rule allow_systemd-user' in result.stderr_text
6d47df
+
6d47df
+        # check for presence
6d47df
+        result = self.master.run_command(
6d47df
+            ['ipa', 'hbacrule-show', 'allow_systemd-user', '--all']
6d47df
+        )
6d47df
+        lines = set(l.strip() for l in result.stdout_text.split('\n'))
6d47df
+        assert 'User category: all' in lines
6d47df
+        assert 'Host category: all' in lines
6d47df
+        assert 'Enabled: TRUE' in lines
6d47df
+        assert 'Services: systemd-user' in lines
6d47df
+        assert 'accessruletype: allow' in lines
6d47df
+
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacsvc-show', 'systemd-user']
6d47df
+        )
6d47df
+
6d47df
+        # only delete rule
6d47df
+        self.master.run_command(
6d47df
+            ['ipa', 'hbacrule-del', 'allow_systemd-user']
6d47df
+        )
6d47df
+
6d47df
+        # run upgrade
6d47df
+        result = self.master.run_command(['ipa-server-upgrade'])
6d47df
+        assert (
6d47df
+            'hbac service systemd-user already exists' in result.stderr_text
6d47df
+        )
6d47df
+        assert (
6d47df
+            'Created hbac rule allow_systemd-user' not in result.stderr_text
6d47df
+        )
6d47df
+        result = self.master.run_command(
6d47df
+            ['ipa', 'hbacrule-show', 'allow_systemd-user'],
6d47df
+            raiseonerr=False
6d47df
+        )
6d47df
+        assert result.returncode != 0
6d47df
+        assert 'HBAC rule not found' in result.stderr_text
6d47df
-- 
6d47df
2.20.1
6d47df