ac7d03
From a4a85c69a945b023b4017ecf4285f9f5e97d5f20 Mon Sep 17 00:00:00 2001
ac7d03
From: David Kupka <dkupka@redhat.com>
ac7d03
Date: Tue, 11 Apr 2017 11:43:40 +0200
ac7d03
Subject: [PATCH] Create system users for FreeIPA services during package
ac7d03
 installation
ac7d03
ac7d03
Previously system users needed by FreeIPA server services was created during
ac7d03
ipa-server-install. This led to problem when DBus policy was configured during
ac7d03
package installation but the user specified in the policy didn't exist yet
ac7d03
(and potentionally similar ones). Now the users will be created in package %pre
ac7d03
section so all users freeipa-server package needs exist before any installation
ac7d03
or configuration begins.
ac7d03
Another possibility would be using systemd-sysusers(8) for this purpose but
ac7d03
given that systemd is not available during container build the traditional
ac7d03
approach is superior.
ac7d03
Also dirsrv and pkiuser users are no longer created by FreeIPA instead it
ac7d03
depends on 389ds and dogtag to create those users.
ac7d03
ac7d03
https://pagure.io/freeipa/issue/6743
ac7d03
ac7d03
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
ac7d03
Reviewed-By: Christian Heimes <cheimes@redhat.com>
ac7d03
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
ac7d03
---
ac7d03
 freeipa.spec.in                            |  9 +++++
ac7d03
 ipaplatform/base/tasks.py                  | 53 ------------------------------
ac7d03
 ipaplatform/redhat/tasks.py                | 26 ---------------
ac7d03
 ipaserver/install/cainstance.py            | 12 -------
ac7d03
 ipaserver/install/dsinstance.py            | 11 -------
ac7d03
 ipaserver/install/httpinstance.py          | 13 --------
ac7d03
 ipaserver/install/installutils.py          | 13 --------
ac7d03
 ipaserver/install/ipa_restore.py           |  7 ----
ac7d03
 ipaserver/install/server/install.py        |  6 +---
ac7d03
 ipaserver/install/server/replicainstall.py |  6 +---
ac7d03
 ipaserver/install/server/upgrade.py        |  2 --
ac7d03
 11 files changed, 11 insertions(+), 147 deletions(-)
ac7d03
ac7d03
diff --git a/freeipa.spec.in b/freeipa.spec.in
ac7d03
index 829c3f0b2898de1ecbf0cfb769fde5cd978c241c..978ebb184f7d051b303940560f44c7a094b071a1 100644
ac7d03
--- a/freeipa.spec.in
ac7d03
+++ b/freeipa.spec.in
ac7d03
@@ -1030,6 +1030,15 @@ if [ -e /usr/sbin/ipa_kpasswd ]; then
ac7d03
 # END
ac7d03
 fi
ac7d03
 
ac7d03
+# create users and groups
ac7d03
+# create kdcproxy group and user
ac7d03
+getent group kdcproxy >/dev/null || groupadd -f -r kdcproxy
ac7d03
+getent passwd kdcproxy >/dev/null || useradd -r -g kdcproxy -s /sbin/nologin -d / -c "IPA KDC Proxy User" kdcproxy
ac7d03
+# create ipaapi group and user
ac7d03
+getent group ipaapi >/dev/null || groupadd -f -r ipaapi
ac7d03
+getent passwd ipaapi >/dev/null || useradd -r -g ipaapi -s /sbin/nologin -d / -c "IPA Framework User" ipaapi
ac7d03
+# add apache to ipaaapi group
ac7d03
+id -Gn apache | grep '\bipaapi\b' >/dev/null || usermod apache -a -G ipaapi
ac7d03
 
ac7d03
 %postun server-trust-ad
ac7d03
 if [ "$1" -ge "1" ]; then
ac7d03
diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py
ac7d03
index 9f91fef2b572a29bf876641fd9ad879604054a2f..3358b7d257cc60ceaecfbbac5155d79b0e63de2e 100644
ac7d03
--- a/ipaplatform/base/tasks.py
ac7d03
+++ b/ipaplatform/base/tasks.py
ac7d03
@@ -22,9 +22,6 @@
ac7d03
 This module contains default platform-specific implementations of system tasks.
ac7d03
 '''
ac7d03
 
ac7d03
-import pwd
ac7d03
-import grp
ac7d03
-
ac7d03
 from pkg_resources import parse_version
ac7d03
 
ac7d03
 from ipaplatform.paths import paths
ac7d03
@@ -186,56 +183,6 @@ class BaseTaskNamespace(object):
ac7d03
 
ac7d03
         raise NotImplementedError()
ac7d03
 
ac7d03
-    def create_system_user(self, name, group, homedir, shell,
ac7d03
-                           uid=None, gid=None, comment=None,
ac7d03
-                           create_homedir=False, groups=None):
ac7d03
-        """Create a system user with a corresponding group"""
ac7d03
-        try:
ac7d03
-            grp.getgrnam(group)
ac7d03
-        except KeyError:
ac7d03
-            log.debug('Adding group %s', group)
ac7d03
-            args = [paths.GROUPADD, '-r', group]
ac7d03
-            if gid:
ac7d03
-                args += ['-g', str(gid)]
ac7d03
-            try:
ac7d03
-                ipautil.run(args)
ac7d03
-                log.debug('Done adding group')
ac7d03
-            except ipautil.CalledProcessError as e:
ac7d03
-                log.critical('Failed to add group: %s', e)
ac7d03
-                raise
ac7d03
-        else:
ac7d03
-            log.debug('group %s exists', group)
ac7d03
-
ac7d03
-        try:
ac7d03
-            pwd.getpwnam(name)
ac7d03
-        except KeyError:
ac7d03
-            log.debug('Adding user %s', name)
ac7d03
-            args = [
ac7d03
-                paths.USERADD,
ac7d03
-                '-g', group,
ac7d03
-                '-d', homedir,
ac7d03
-                '-s', shell,
ac7d03
-                '-r', name,
ac7d03
-            ]
ac7d03
-            if uid:
ac7d03
-                args += ['-u', str(uid)]
ac7d03
-            if comment:
ac7d03
-                args += ['-c', comment]
ac7d03
-            if create_homedir:
ac7d03
-                args += ['-m']
ac7d03
-            else:
ac7d03
-                args += ['-M']
ac7d03
-            if groups is not None:
ac7d03
-                args += ['-G', groups.join(',')]
ac7d03
-            try:
ac7d03
-                ipautil.run(args)
ac7d03
-                log.debug('Done adding user')
ac7d03
-            except ipautil.CalledProcessError as e:
ac7d03
-                log.critical('Failed to add user: %s', e)
ac7d03
-                raise
ac7d03
-        else:
ac7d03
-            log.debug('user %s exists', name)
ac7d03
-
ac7d03
     @staticmethod
ac7d03
     def parse_ipa_version(version):
ac7d03
         """
ac7d03
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
ac7d03
index d0ef5fbd1ceb8110dd417dda44a74dc63898456a..07efebab97eabcf2dc39bd345920a1c7be56e9f5 100644
ac7d03
--- a/ipaplatform/redhat/tasks.py
ac7d03
+++ b/ipaplatform/redhat/tasks.py
ac7d03
@@ -431,32 +431,6 @@ class RedHatTaskNamespace(BaseTaskNamespace):
ac7d03
 
ac7d03
         return True
ac7d03
 
ac7d03
-    def create_system_user(self, name, group, homedir, shell,
ac7d03
-                           uid=None, gid=None, comment=None,
ac7d03
-                           create_homedir=False, groups=None):
ac7d03
-        """
ac7d03
-        Create a system user with a corresponding group
ac7d03
-
ac7d03
-        According to https://fedoraproject.org/wiki/Packaging:UsersAndGroups?rd=Packaging/UsersAndGroups#Soft_static_allocation
ac7d03
-        some system users should have fixed UID, GID and other parameters set.
ac7d03
-        This values should be constant and may be hardcoded.
ac7d03
-        Add other values for other users when needed.
ac7d03
-        """
ac7d03
-        if name == constants.PKI_USER:
ac7d03
-            if uid is None:
ac7d03
-                uid = 17
ac7d03
-            if gid is None:
ac7d03
-                gid = 17
ac7d03
-            if comment is None:
ac7d03
-                comment = 'CA System User'
ac7d03
-        if name == constants.DS_USER:
ac7d03
-            if comment is None:
ac7d03
-                comment = 'DS System User'
ac7d03
-
ac7d03
-        super(RedHatTaskNamespace, self).create_system_user(
ac7d03
-            name, group, homedir, shell, uid, gid, comment, create_homedir,
ac7d03
-            groups)
ac7d03
-
ac7d03
     def parse_ipa_version(self, version):
ac7d03
         """
ac7d03
         :param version: textual version
ac7d03
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
ac7d03
index 3980e412603437b0db5804623f6626d11e52c009..ac5d9e2fc633c5ad732670245b72bee0f03268a6 100644
ac7d03
--- a/ipaserver/install/cainstance.py
ac7d03
+++ b/ipaserver/install/cainstance.py
ac7d03
@@ -46,7 +46,6 @@ from ipalib import errors
ac7d03
 import ipalib.constants
ac7d03
 from ipalib.install import certmonger
ac7d03
 from ipaplatform import services
ac7d03
-from ipaplatform.constants import constants
ac7d03
 from ipaplatform.paths import paths
ac7d03
 from ipaplatform.tasks import tasks
ac7d03
 
ac7d03
@@ -263,16 +262,6 @@ def is_ca_installed_locally():
ac7d03
     return os.path.exists(paths.CA_CS_CFG_PATH)
ac7d03
 
ac7d03
 
ac7d03
-def create_ca_user():
ac7d03
-    """Create PKI user/group if it doesn't exist yet."""
ac7d03
-    tasks.create_system_user(
ac7d03
-        name=constants.PKI_USER,
ac7d03
-        group=constants.PKI_GROUP,
ac7d03
-        homedir=paths.VAR_LIB,
ac7d03
-        shell=paths.NOLOGIN,
ac7d03
-    )
ac7d03
-
ac7d03
-
ac7d03
 class CAInstance(DogtagInstance):
ac7d03
     """
ac7d03
     When using a dogtag CA the DS database contains just the
ac7d03
@@ -382,7 +371,6 @@ class CAInstance(DogtagInstance):
ac7d03
             has_ra_cert = False
ac7d03
 
ac7d03
         if not ra_only:
ac7d03
-            self.step("creating certificate server user", create_ca_user)
ac7d03
             if promote:
ac7d03
                 # Setup Database
ac7d03
                 self.step("creating certificate server db", self.__create_ds_db)
ac7d03
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
ac7d03
index 72fcb65f2eb699d0077d3c5cc02a3fcaaad9b8e5..99a1781ca4475805e9bf3b2bac3f26b5fb107a43 100644
ac7d03
--- a/ipaserver/install/dsinstance.py
ac7d03
+++ b/ipaserver/install/dsinstance.py
ac7d03
@@ -158,16 +158,6 @@ def is_ds_running(server_id=''):
ac7d03
     return services.knownservices.dirsrv.is_running(instance_name=server_id)
ac7d03
 
ac7d03
 
ac7d03
-def create_ds_user():
ac7d03
-    """Create DS user/group if it doesn't exist yet."""
ac7d03
-    tasks.create_system_user(
ac7d03
-        name=DS_USER,
ac7d03
-        group=DS_USER,
ac7d03
-        homedir=paths.VAR_LIB_DIRSRV,
ac7d03
-        shell=paths.NOLOGIN,
ac7d03
-    )
ac7d03
-
ac7d03
-
ac7d03
 def get_domain_level(api=api):
ac7d03
     ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm)
ac7d03
     conn = ipaldap.LDAPClient(ldap_uri)
ac7d03
@@ -258,7 +248,6 @@ class DsInstance(service.Service):
ac7d03
 
ac7d03
     def __common_setup(self):
ac7d03
 
ac7d03
-        self.step("creating directory server user", create_ds_user)
ac7d03
         self.step("creating directory server instance", self.__create_instance)
ac7d03
         self.step("enabling ldapi", self.__enable_ldapi)
ac7d03
         self.step("configure autobind for root", self.__root_autobind)
ac7d03
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
ac7d03
index 45bf479d1088c3b3396d955bf2592c4bce1e886f..8e444be2d23ec5e7890d221508bc866de2854c89 100644
ac7d03
--- a/ipaserver/install/httpinstance.py
ac7d03
+++ b/ipaserver/install/httpinstance.py
ac7d03
@@ -102,18 +102,6 @@ def httpd_443_configured():
ac7d03
     return False
ac7d03
 
ac7d03
 
ac7d03
-def create_kdcproxy_user():
ac7d03
-    """Create KDC proxy user/group if it doesn't exist yet."""
ac7d03
-    tasks.create_system_user(
ac7d03
-        name=KDCPROXY_USER,
ac7d03
-        group=KDCPROXY_USER,
ac7d03
-        homedir=paths.VAR_LIB_KDCPROXY,
ac7d03
-        shell=paths.NOLOGIN,
ac7d03
-        comment="IPA KDC Proxy User",
ac7d03
-        create_homedir=True,
ac7d03
-    )
ac7d03
-
ac7d03
-
ac7d03
 class WebGuiInstance(service.SimpleServiceInstance):
ac7d03
     def __init__(self):
ac7d03
         service.SimpleServiceInstance.__init__(self, "ipa_webgui")
ac7d03
@@ -183,7 +171,6 @@ class HTTPInstance(service.Service):
ac7d03
                   self.remove_httpd_ccaches)
ac7d03
         self.step("configuring SELinux for httpd", self.configure_selinux_for_httpd)
ac7d03
         if not self.is_kdcproxy_configured():
ac7d03
-            self.step("create KDC proxy user", create_kdcproxy_user)
ac7d03
             self.step("create KDC proxy config", self.create_kdcproxy_conf)
ac7d03
             self.step("enable KDC proxy", self.enable_kdcproxy)
ac7d03
         self.step("starting httpd", self.start)
ac7d03
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
ac7d03
index ef6a399ad28ae8b8646864baea9965f762050484..9230e70056b1a773246a0d95e6ecb943cada953c 100644
ac7d03
--- a/ipaserver/install/installutils.py
ac7d03
+++ b/ipaserver/install/installutils.py
ac7d03
@@ -44,7 +44,6 @@ import six
ac7d03
 from six.moves.configparser import SafeConfigParser, NoOptionError
ac7d03
 # pylint: enable=import-error
ac7d03
 
ac7d03
-from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
ac7d03
 from ipalib.install import sysrestore
ac7d03
 from ipalib.install.kinit import kinit_password
ac7d03
 import ipaplatform
ac7d03
@@ -56,7 +55,6 @@ from ipalib import api, errors, x509
ac7d03
 from ipapython.dn import DN
ac7d03
 from ipaserver.install import certs, service, sysupgrade
ac7d03
 from ipaplatform import services
ac7d03
-from ipaplatform.constants import constants
ac7d03
 from ipaplatform.paths import paths
ac7d03
 from ipaplatform.tasks import tasks
ac7d03
 
ac7d03
@@ -1515,14 +1513,3 @@ def default_subject_base(realm_name):
ac7d03
 
ac7d03
 def default_ca_subject_dn(subject_base):
ac7d03
     return DN(('CN', 'Certificate Authority'), subject_base)
ac7d03
-
ac7d03
-
ac7d03
-def create_ipaapi_user():
ac7d03
-    """Create IPA API user/group if it doesn't exist yet."""
ac7d03
-    tasks.create_system_user(
ac7d03
-        name=IPAAPI_USER,
ac7d03
-        group=IPAAPI_GROUP,
ac7d03
-        homedir=paths.VAR_LIB,
ac7d03
-        shell=paths.NOLOGIN
ac7d03
-    )
ac7d03
-    tasks.add_user_to_group(constants.HTTPD_USER, IPAAPI_GROUP)
ac7d03
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
ac7d03
index 2552bbdef36f653f1c377ea096ca227d09e5f3e6..378c013b6f4a4656768d7a484d2014a0f9eef3c0 100644
ac7d03
--- a/ipaserver/install/ipa_restore.py
ac7d03
+++ b/ipaserver/install/ipa_restore.py
ac7d03
@@ -36,8 +36,6 @@ from ipapython import version, ipautil
ac7d03
 from ipapython.ipautil import run, user_input
ac7d03
 from ipapython import admintool
ac7d03
 from ipapython.dn import DN
ac7d03
-from ipaserver.install.dsinstance import create_ds_user
ac7d03
-from ipaserver.install.cainstance import create_ca_user
ac7d03
 from ipaserver.install.replication import (wait_for_task, ReplicationManager,
ac7d03
                                            get_cs_replication_manager)
ac7d03
 from ipaserver.install import installutils
ac7d03
@@ -296,7 +294,6 @@ class Restore(admintool.AdminTool):
ac7d03
                     not user_input("Continue to restore?", False)):
ac7d03
                 raise admintool.ScriptError("Aborted")
ac7d03
 
ac7d03
-        create_ds_user()
ac7d03
         pent = pwd.getpwnam(constants.DS_USER)
ac7d03
 
ac7d03
         # Temporary directory for decrypting files before restoring
ac7d03
@@ -379,15 +376,11 @@ class Restore(admintool.AdminTool):
ac7d03
             # We do either a full file restore or we restore data.
ac7d03
             if restore_type == 'FULL':
ac7d03
                 self.remove_old_files()
ac7d03
-                if 'CA' in self.backup_services:
ac7d03
-                    create_ca_user()
ac7d03
                 self.cert_restore_prepare()
ac7d03
                 self.file_restore(options.no_logs)
ac7d03
                 self.cert_restore()
ac7d03
                 if 'CA' in self.backup_services:
ac7d03
                     self.__create_dogtag_log_dirs()
ac7d03
-                if http.is_kdcproxy_configured():
ac7d03
-                    httpinstance.create_kdcproxy_user()
ac7d03
 
ac7d03
             # Always restore the data from ldif
ac7d03
             # We need to restore both userRoot and ipaca.
ac7d03
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
ac7d03
index bf2e248dceaae36ba0030d3eaa47976f51ce60ba..197f01ccef58bb3564eb4c6b5b4d615bff1e523d 100644
ac7d03
--- a/ipaserver/install/server/install.py
ac7d03
+++ b/ipaserver/install/server/install.py
ac7d03
@@ -39,7 +39,7 @@ from ipaserver.install import (
ac7d03
 from ipaserver.install.installutils import (
ac7d03
     IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
ac7d03
     is_ipa_configured, load_pkcs12, read_password, verify_fqdn,
ac7d03
-    update_hosts_file, create_ipaapi_user)
ac7d03
+    update_hosts_file)
ac7d03
 
ac7d03
 if six.PY3:
ac7d03
     unicode = str
ac7d03
@@ -721,12 +721,8 @@ def install(installer):
ac7d03
         update_hosts_file(ip_addresses, host_name, fstore)
ac7d03
 
ac7d03
     # Make sure tmpfiles dir exist before installing components
ac7d03
-    create_ipaapi_user()
ac7d03
     tasks.create_tmpfiles_dirs()
ac7d03
 
ac7d03
-    # Create DS user/group if it doesn't exist yet
ac7d03
-    dsinstance.create_ds_user()
ac7d03
-
ac7d03
     # Create a directory server instance
ac7d03
     if not options.external_cert_files:
ac7d03
         # Configure ntpd
ac7d03
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
ac7d03
index 6f1a0d6d29b20d53986205a63382a385e75f80ea..b82d7b474640e24da7d978e9546ebd7a8e602c29 100644
ac7d03
--- a/ipaserver/install/server/replicainstall.py
ac7d03
+++ b/ipaserver/install/server/replicainstall.py
ac7d03
@@ -41,8 +41,7 @@ from ipaserver.install import (
ac7d03
     installutils, kra, krbinstance,
ac7d03
     ntpinstance, otpdinstance, custodiainstance, service)
ac7d03
 from ipaserver.install.installutils import (
ac7d03
-    create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured,
ac7d03
-    create_ipaapi_user)
ac7d03
+    create_replica_config, ReplicaConfig, load_pkcs12, is_ipa_configured)
ac7d03
 from ipaserver.install.replication import (
ac7d03
     ReplicationManager, replica_conn_check)
ac7d03
 import SSSDConfig
ac7d03
@@ -1347,7 +1346,6 @@ def install(installer):
ac7d03
     ccache = os.environ['KRB5CCNAME']
ac7d03
 
ac7d03
     # Make sure tmpfiles dir exist before installing components
ac7d03
-    create_ipaapi_user()
ac7d03
     tasks.create_tmpfiles_dirs()
ac7d03
 
ac7d03
     if promote:
ac7d03
@@ -1376,8 +1374,6 @@ def install(installer):
ac7d03
         ntp = ntpinstance.NTPInstance()
ac7d03
         ntp.create_instance()
ac7d03
 
ac7d03
-    dsinstance.create_ds_user()
ac7d03
-
ac7d03
     try:
ac7d03
         if promote:
ac7d03
             conn.connect(ccache=ccache)
ac7d03
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
ac7d03
index 25b86297af3ae9d5f21cebb93f493b90670dcfc3..927acb011172de926773196eb1d032af8376f3d9 100644
ac7d03
--- a/ipaserver/install/server/upgrade.py
ac7d03
+++ b/ipaserver/install/server/upgrade.py
ac7d03
@@ -1652,7 +1652,6 @@ def upgrade_configuration():
ac7d03
 
ac7d03
     if not http.is_kdcproxy_configured():
ac7d03
         root_logger.info('[Enabling KDC Proxy]')
ac7d03
-        httpinstance.create_kdcproxy_user()
ac7d03
         http.create_kdcproxy_conf()
ac7d03
         http.enable_kdcproxy()
ac7d03
 
ac7d03
@@ -1837,7 +1836,6 @@ def upgrade_check(options):
ac7d03
 
ac7d03
 def upgrade():
ac7d03
     # Do this early so that any code depending on these dirs will not fail
ac7d03
-    installutils.create_ipaapi_user()
ac7d03
     tasks.create_tmpfiles_dirs()
ac7d03
     tasks.configure_tmpfiles()
ac7d03
 
ac7d03
-- 
ac7d03
2.9.3
ac7d03