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

From: Bob Proulx <[email-masked]>
Date: Mon, 18 Feb 2013 14:01:03 -0700

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.

> 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.

> 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.

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.

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.

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

Bob