Using the getent command#

The command getent is not known to many users but it is very useful when you need to get information about users, groups, or other entities. The command can be used to get information about users, groups, or other entities for example without having to know where the information is stored.

The syntax of the getent command is simple to use as it takes the name of the data source and possibly the name of the entry to retrieve.

getent database [key ...]

The Name Service Switch (NSS) service allows you to specify which data sources are used to retrieve data and is configured in the /etc/nsswitch.conf file. This is the technology behind the getent command to query data sources like local files, but also LDAP and Active Directory.

$ cat /etc/nsswitch.conf
# Generated by authselect on Thu Apr 21 23:28:16 2022
# Do not modify this file manually, use authselect instead.
# Any user changes will be overwritten.
# You can stop authselect from managing your configuration by calling 'authselect opt-out'.
# See authselect(8) for more details.

# In order of likelihood of use to accelerate lookup.
passwd:     files sss systemd
shadow:     files
group:      files sss systemd
hosts:      files myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns
services:   files sss
netgroup:   files sss
automount:  files sss

aliases:    files
ethers:     files
gshadow:    files
networks:   files dns
protocols:  files
publickey:  files
rpc:        files

Warning

Changing the order of the data sources can have unintended consequences like delays in the lookup process or not finding the entry you are looking for. Consult the documentation for more information.

User and group lookups#

As in the example below, a lot of users directly access the file /etc/passwd to retrieve user information. The downside is that all information found in LDAP or Active Directory is lost.

$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
...

With the getent command, you can retrieve the user information from the /etc/passwd file.

$ getent passed
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
...

But the getent command can also used to retrieve a specific user or group name.

$ getent passwd root
root:x:0:0:root:/root:/bin/bash
$ getent group wheel
wheel:x:10:user01,user02

The query can also be done the other way around and specify the numerical identifier for an user or group and still retrieve the record.

$ getent passwd 0
root:x:0:0:root:/root:/bin/bash

This is already easier than using grep or awk to retrieve the information from local files only and can clean up your shellcode to make them more readable and less error-prone.

Query network databases#

Older data sources that are still available, but are used less and less are for example stored in /etc/services, /etc/hosts, and /etc/networks. Information from these data sources is used in commands like netstat and ss to map used ports to easily to read names for the user.

The services data source is used to map port numbers to service names like for the service ssh on port 22 for example. Also here it is only given the data source you want to query and the key value to query for.

$ getent services 22
ssh                   22/tcp
$ getent services ssh
ssh                   22/tcp

The same goes for the hosts and networks data source, but the usage of these is on a decline since the introduction of DNS and should be considered deprecated. Some application still rely on them, but it will be clearly stated in the documentation of the application.

$ getent networks
default               0.0.0.0
loopback              127.0.0.0
link-local            169.254.0.0
$ getent hosts
127.0.0.1       localhost localhost.localdomain localhost4 localhost4.localdomain4
127.0.0.1       localhost localhost.localdomain localhost6 localhost6.localdomain6

More data sources exist, but like the above, they are not used very often as their use-case disappeared over time. In legacy environments, they still may be used, but it is rapidly decreasing.

Privileged databases#

The Name Service Switch (NSS) service behind getent has very basic access control and leaves that to the data source to handle. In the example below the shadow data source is not accessible to the user as the files are only readable by the root user.

$ getent shadow

If we run the same command as root, we get the following output and it shows all information available. In the example, no password hashes are shown, but it does show which accounts are disabled and which are expired, and which password hash is used.

# getent shadow
root:!::0:99999:7:::
bin:*:17589:0:99999:7:::
daemon:*:17589:0:99999:7:::
adm:*:17589:0:99999:7:::
lp:*:17589:0:99999:7:::
sync:*:17589:0:99999:7:::
...

Exit codes for programming#

The key benefit of using getent is that it returns an exit code that can be used to check if the command was successful and with only four exit codes, you can easily determine if the command was successful or not.

  • 0 - Command completed successfully.

  • 1 - Missing arguments, or database unknown.

  • 2 - One or more supplied key could not be found in the database.

  • 3 - Enumeration not supported on this database.

In the example below we use the getent command to retrieve the user information for the user root which returns an exit code of 0. If we query for a none existing user the command will return an exit code of 2 and the output will be empty.

$ getent passwd root
root:x:0:0:root:/root:/bin/bash
$ echo $?
0
$ getent passwd unknown-user
$ echo $?
2

Common use-cases#

Some common use-cases to use getent besides only using it to query data are listed below to start helping to use it more often.

Retrieving user information for the current user:

$ getent passwd `whoami`
user01:x:1000:1000:user01:/home/user01:/bin/bash

Quickly generate a list of all users with a locked account:

# getent shadow | grep '^[^:]\+:!' | cut -d: -f1
root
apache
systemd-coredump
systemd-network
systemd-resolve
dbus
polkitd
...

Quickly search for the next available user ID for non-system users and below the Dynamic User ID range reserved for systemd:

$ getent passwd | awk -F: '($3>999) && ($3<61184) && ($3>max) { max=$3 } END { print max+1 }'
1002