Subject: Re: bug#13738: Add --all option to 'users' command

From: anatoly techtonik <[email-masked]>
Date: Sun, 10 Feb 2019 16:42:03 +0300

On Tue, Feb 19, 2013 at 12:01 AM Bob Proulx <[email-masked]> wrote:
>
> anatoly techtonik wrote:
> > Bob Proulx wrote:
> > > anatoly techtonik wrote:
> > > > The 'users' command shows users who are currently online. It will be nice
> > > > to have --all option to show all users.
> > >
> > > Do you mean the equivelent to this?
> > >
> > >   $ getent passwd | awk -F: '{print$1}'
> >
> > Yes. And also - the equivalent of this as it appeared more useful:
> > $ cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
>
> That is an incorrect implementation.  It's buggy.
>
> > http://askubuntu.com/questions/257421/list-all-human-users/257451
>
> I looked at that reference and it says this:
>
> > Human users have UIDs starting at 1000,
>
> That assumption is incorrect.  Many systems start users off at 100.
> Many others start users at 500.  There isn't any univerial standard.
> It is a local system configuration option.

How to figure out at which number users UIDs start at a given system?

> > so you can use that fact to filter out the non-humans:
> >
> > cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1
>
> This assumes that /etc/passwd is the user database.  While true on a
> typical standalone system it is incorrect when NIS/yp or LDAP or other
> account system is in use.  That is why I used 'getent passwd' even
> though it is not available on all systems.  When available it obeys
> the local system configuration and returns the correct information.

If NIS/yp or LDAP are installed, they provide getent, right? So if there is
no getent, then /etc/passwd is de-facto database and can be reliably used
as a fallback. Is that correct?

> > This cuts the first (username) and third (UID) colon-delimited fields
> > from /etc/passwd, then filters for the resulting lines which end with
> > a colon and four digits, then cuts the first (username) field from
> > that, leaving you with a list of users with UIDs between 1000 and
> > 9999.
> >
> > If you have more than nine thousand users on your system, this will
> > fail - but it's necessary to restrict the result to 4-digit UIDs in
> > order not to catch nobody (UID 65534).
>
> The above is admittedly incorrect when users have uids larger than
> 9999.  But users with larger uids are very common.  I know several
> organizations that assign the user's phone number as their uid for
> example as a way to simplify coordination.  Printing only four digit
> uids would be unsuitable.
>
> In order to list users but avoid listing certain specific users the
> typical way used by NIS/yp for example is to set a min and a max uid
> value in the nis/yp configuration.
>
>   $ ypcat passwd  # avoids listing below MINUID / above MAXUID (example)
>
> Which means something like this would be needed.
>
>   $ getent passwd | awk -F: -v minuid=1000 -v maxuid=65533 'minuid <= $3 && $3 <= maxuid { print $1 }'
>
> Where the values 1000 and 65533 would be local system definable values.

Is there other way to distinguish user accounts other than matching
"things that only seem to be true", like UID numbers?

> Actually even that isn't sufficient.  The value for nobody 65534 is a
> traditional value.  But uids may be larger on most modern systems.  It
> isn't unusual to have the nobody id in the middle of the range with
> real users having uid numbers both less than and greater than that
> value.  Therefore in order to be completely correct additional filter
> methods would be needed such as sets of ranges or block lists or
> something similar.

Yes. I believe LXD has UID mapping for containers about 100000,
and those are not human users in general case.

> Solving the problem in general gets messy very quickly.  It is
> therefore one of those that is better solved locally by providing the
> tools needed to do what is needed on a case by case basis.  So far
> after forty years of Unix and GNU systems this hasn't been needed and
> therefore the use cases must be unusual.  The philosophy isn't to
> solve all problems but just to make all problems solvable.

I guess appeal to tradition in the major argument in Linux reasoning. )
I am getting the feeling that the approach of solving problems be using
the tool for specific case is misleading in the case that it battles with
effects and not the causes. The cause of the mess if UID mapping in
Linux kernel, which is not about users at all. There is a concept of user
space, but correct me if I wrong - daemons that run with different UIDs
are run in their own userspace as well. The user concept is not defined
by kernel, but rather by some concept of having home and being able to
login into it either from console or remotely.

If this behavior of humans vs daemons was explicitly documented
somewhere, it could lead to better understanding if solving this problem
in general is real.

> It would help if you could say a few words about the case in
> which this would be helpful?

Sorry that I've missed the reply. The case is to see if there are any
alive users on the systems I manage or help with. An easy way to
check servers for accounts left from former developers.
-- 
anatoly t.