Bug 1472369 - Improve heuristic for allocation of new uids and gids when creating users and groups
Improve heuristic for allocation of new uids and gids when creating users and...
Status: NEW
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: shadow-utils (Show other bugs)
All Linux
unspecified Severity unspecified
: rc
: ---
Assigned To: Tomas Mraz
BaseOS QE Security Team
Depends On:
  Show dependency treegraph
Reported: 2017-07-18 11:02 EDT by Przemysław Kulczycki
Modified: 2017-11-28 11:02 EST (History)
5 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description Przemysław Kulczycki 2017-07-18 11:02:43 EDT
Description of problem:
Postinstall scripts of the pacemaker package are unable to create the necessary group haclient and the dependent user hacluster when PolicyKit (pkg: polkit) is already installed and (as a consequence) the polkitd group is created with a conflicting GID 189.

Version-Release number of selected component (if applicable):
RHEL 7.3
Name        : pacemaker
Arch        : x86_64
Version     : 1.1.15
Release     : 11.el7_3.5
Repo        : rhel-ha-for-rhel-7-server-rpms/7Server/x86_64

How reproducible:
At every clean install of pacemaker

Steps to Reproduce:
1. Make sure that user hacluster and group haclient is not present
2. Install the pacemaker package
3. Watch the yum output for the following messages:
groupadd: GID '189' already exists
useradd: group 'haclient' does not exist
warning: user hacluster does not exist - using root
warning: group haclient does not exist - using root

Actual results:
Pacemaker is installed, but the required user hacluster and group haclient is not created automatically
[upr@cfproxy04 ~]$ egrep 'haclient|hacluster|polkit' /etc/passwd /etc/group
/etc/passwd:polkitd:x:200:189:User for polkitd:/:/sbin/nologin
[upr@cfproxy04 ~]$ rpm -q pacemaker

Expected results:
user hacluster and group haclient is created automatically when installing the pacemaker package, without using a fixed UID 189 and GID 189.

Additional info:
Comment 1 Przemysław Kulczycki 2017-07-18 11:09:40 EDT
As noted in Bug 908447 these IDs are reserverd in the setup package.

[upr@cfproxy04 ~]$ grep 189 /usr/share/doc/setup-2.8.71/uidgid
hacluster       189     -       /               /sbin/nologin   pacemaker
haclient        -       189     -               -       pacemaker
Comment 2 Ken Gaillot 2017-07-18 11:24:52 EDT
Reassigning to polkit, which should reserve a different group id if a fixed one is required
Comment 3 Przemysław Kulczycki 2017-07-18 11:26:22 EDT
[upr@cfproxy04 tmp]$ rpm -qp --scripts polkit-0.112-12.el7_3.x86_64.rpm
preinstall scriptlet (using /bin/sh):
getent group polkitd >/dev/null || groupadd -r polkitd
getent passwd polkitd >/dev/null || useradd -r -g polkitd -d / -s /sbin/nologin -c "User for polkitd" polkitd
exit 0
Comment 4 Jan Pokorný 2017-07-18 12:03:24 EDT
Cannot this be a matter of non-default SYS_UID_MIN and SYS_GID_MIN
(both are set to 201 in /etc/login.defs in my installation) when
installing polkit?
Comment 5 Miloslav Trmač 2017-07-18 12:41:23 EDT
(In reply to Jan Pokorný from comment #4)
> Cannot this be a matter of non-default SYS_UID_MIN and SYS_GID_MIN
> (both are set to 201 in /etc/login.defs in my installation) when
> installing polkit?

Indeed, except that it is SYS_[UG]ID_MAX set to 999; ({user,group}add -r) without a specified ID value uses the highest free one.  For example, a completely default RHEL 7.3 interactive install ends up with polkitd UID 998, GID 996 for me.

How did polkit end up with GID 189?

How exactly did you install the OS? What does (grep '[UG]ID' /etc/login.defs) output? If /etc/login.defs is modified from the OS default at all, by what?
Comment 7 Przemysław Kulczycki 2017-07-19 05:24:59 EDT
Ok, it appears my company is using a custom version of /etc/login.defs
[upr@cfproxy04 tmp]$ cat /etc/login.defs
# This file is automatically handled by puppet (authentication) - all manual changes will be overwritten!
MAIL_DIR        /var/spool/mail
UID_MIN                   500
UID_MAX                   41999
GID_MIN                   500
GID_MAX                   41999
UMASK           077

It lacks the SYS_GID_MIN and SYS_UID_MIN variables.
I guess it makes this bug report irrelevant.
Comment 8 Przemysław Kulczycki 2017-07-19 05:32:18 EDT
Is there any technical reason that the pacemaker account and group has to have a 189 UID/GID?
Comment 9 Jan Pokorný 2017-07-19 10:10:44 EDT
re [comment 8]:

Original request is here: [bug 872208].
Upstream "setup" project modification:

It seems that the reasoning was, amongst others, firm grounds for the
remote shell access or similar interactions in the distributed computing.

See also Fedora packaging guidelines for the particular topic:

The soft static allocation relies on distro-native login.defs file.
Comment 10 Miloslav Trmač 2017-07-19 14:04:27 EDT
> Ok, it appears my company is using a custom version of /etc/login.defs

Thanks for the diagnosis.

(In reply to Przemysław Kulczycki from comment #8)
> Is there any technical reason that the pacemaker account and group has to
> have a 189 UID/GID?

Jan has pointed out to the general guidelines (in short, accounts which may access a filesystem or a similar resource over the network need to have a shared UID).  Focusing _specifically_ on pacemaker is not ultimately worthwhile; there will always be _something_ using a pre-allocated ID value, and we are now well into the 190’s in Fedora.  If it’s not pacemaker, it will be something else.

Though, reassigning to shadow-utils for consideration of one trade-off in this:

The current code (find_new_gid) is trying not to fill in “holes” in the allocated ID space (to minimize the risk of reusing a previously used ID), by finding lowest_found, the lowest allocated GID in the (SYS_GID_{MIN,MAX}) range and using lowest_found-1 if it is available.

That works perfectly fine with the default setup of SYS_GID_(MIN,MAX) = (201,999), with statically allocated GIDs < 201, and lowest_found in the 990s.

But, with the values unspecified as in comment #7, SYS_GID_MIN defaults to 101; i.e. if any package with a statically allocated GID in the [101,200] range is installed (in this case, certainly systemd-journal, GID 190), lowest_found ≤ 190, i.e. the code will start allocating dynamic GIDs overlapping the statically-allocated range even if there are hundreds of higher GID values available.

It seems that when trying to allocate static ID values from bottom up and dynamic from top down, skipping the vast majority of the dynamic area, i.e. increasing, not decreasing, the risk of collision, seems suboptimal and not really worth the risk of reusing a previously allocated value.

I can’t think of a reasonable fix or whether this should just be called a misconfiguration; we could perhaps stop the lowest_found search at the highest “hole” of N (64?) free GIDs, regardless of GIDs allocated below, but that’s also an ugly a fragile heuristic. Changing the default for SYS_GID_MIN is out of the question I guess.
Comment 11 Tomas Mraz 2017-07-20 03:51:27 EDT
I actually believe that adding the suggested heuristic would be nice improvement. I mean the 'skipping holes' behavior is just a heuristic as well so adding one more hint should not harm anything.

Perhaps the hole size could be even configurable, but that would require upstream acceptance for adding a new configuration value.

Note You need to log in before you can comment on or make changes to this bug.