147

I want a command to list all users who have root privileges i.e. sudo ?

Suppose I'm a sudoer user. How could I know all other sudoer users?

sigdelsanjog
  • 7,110
Maythux
  • 84,289
  • Here is the answer: http://unix.stackexchange.com/a/140974/107084 – A.B. Apr 20 '15 at 11:00
  • 1
    I find this one nice http://unix.stackexchange.com/questions/50785/how-do-i-find-out-if-i-am-sudoer – JoKeR Apr 20 '15 at 11:31
  • @JoKeR nice and tricky – Maythux Apr 20 '15 at 11:33
  • 1
    Note that only Joker and muru's answers are correct, only parsing user/group conf files does not give you who has the sudo permission and who has not....if a user is in sudo group but the sudoers file has nothing mentioned for sudo group, then? – heemayl Apr 20 '15 at 16:32

9 Answers9

143

If you just need to list the sudoers listed in the sudo group, I think that the best way to do it would be to run this command (which should be computationally lighter than any of the other commands in this answer):

grep -Po '^sudo.+:\K.*$' /etc/group

Also as suggested in the comments by muru, the format of the entries in /etc/group can be easily handled by cut:

grep '^sudo:.*$' /etc/group | cut -d: -f4

Also again as suggested in the comments by muru, one can use getent in place of grep:

getent group sudo | cut -d: -f4

Any of these commands will print all the users listed in the sudo group in /etc/group (if any).

Command #1 breakdown:

  • grep: Prints all the lines matching a regex in a file
  • -P: makes grep match Perl-style regexes
  • o: makes grep print only the matched string
  • '^sudo.+:\K.*$': makes grep match the regex between the quotes

Regex #1 breakdown:

  • Any character or group of characters not listed matches the character or the group of characters itself
  • ^: start of line
  • .+: one or more characters
  • \K: discard the previous match
  • .*: zero or more characters
  • $: end of line

Command #2 breakdown:

  • grep: Prints all the lines matching a regex in a file
  • '^sudo.+:\K.*$': makes grep match the regex between the quotes
  • cut: Prints only a specified section of each line in a file
  • -d:: makes cut interpret : as a field delimiter
  • -f4: makes cut print only the fourth field

Regex #2 breakdown:

  • Any character or group of characters not listed matches the character or the group of characters itself
  • ^: start of line
  • .*: zero or more characters
  • $: end of line
kos
  • 35,891
  • 6
    -1: this won't catch other users or groups who may have been added to sudoers, or external sources like LDAP, and boy is it an ugly way to do this. getent group sudo | cut -d: -f4, or use awk, but either way remember that group and passwd have fixed formats, with delimiters. – muru Apr 20 '15 at 13:06
  • @muru You're right, I updated my answer – kos Apr 20 '15 at 13:47
  • @kos Also note the you really should use getent group - you don't need the grep at all. getent group foo is like grep foo /etc/group, but more capable. – muru Apr 20 '15 at 13:51
  • @muru I didn't know getent at all, any tought on how grep and getent compare computationally? Would it be lighter to run getent? – kos Apr 20 '15 at 14:02
  • @kos I hope not. getent has access to more databases than /etc/passwd, it should certainly be doing more work. On the other hand, it is a dedicated tool. – muru Apr 20 '15 at 14:16
  • You may use awk, awk -F: '/^sudo/{print $NF}' /etc/group – Avinash Raj Apr 20 '15 at 14:19
  • @muru Ok, I added the getent option as a third "possibly heavier" option – kos Apr 20 '15 at 15:18
  • @AvinashRaj I think that the difference here should be really minor (if there's a difference at all), but any tought on how grep and awk compare performance-wise? – kos Apr 20 '15 at 15:21
  • 1
    This answer assumes that all sudoers are members of the sudo group. Some unixes have other groups such as wheel. The answer by @muru will include all sudoers no matter what groups they are in. – Simon Woodside Mar 14 '17 at 06:17
  • this popular answer is a vivid example of how unusable everything "linux" is ... – Anbu Agarwal Oct 18 '22 at 06:32
40

As it stated here I consider the simpliest way to discover with -l & -U options together, just type users it will list e.g.: John then:

If the user has sudo access, it will print the level of sudo access for that particular user:

  sudo -l -U John
  User John may run the following commands on this host:
     (ALL : ALL) ALL

If the user don't have sudo access, it will print that a user is not allowed to run sudo on localhost:

   sudo -l -U John
   User John is not allowed to run sudo on localhost.
JoKeR
  • 6,972
  • 9
  • 43
  • 65
  • 2
    You could loop through all the normal users and return the details on them using something like: for u in $(awk -F'[/:]' '{if($3>=1000&&$3!=65534) print $1}' /etc/passwd); do sudo -lU "$u" ; done. quick hack nothing guaranteed :) – Wilf Jun 08 '15 at 20:09
  • This also works in a active directory setup. For instance you can pick a user from some special group and check on the user. If you added the AD group correctly something like "%domain admins@mycompany.intra" ALL=(ALL) ALL then it works. You saved me a lot of time, because I was unaware this works for non-local users as well. – AdamKalisz May 26 '17 at 10:11
19

Expanding on the sudo -l -U test, one can use getent passwd to determine the users who can use sudo. Using getent allows us to access users who may not be present in the passwd file, such as LDAP users:

getent passwd | cut -f1 -d: | sudo xargs -L1 sudo -l -U | grep -v 'not allowed'

sudo -U does not return a non-zero exit value that we could take advantage of, so we are reduced to grepping the output.

muru
  • 197,895
  • 55
  • 485
  • 740
17

As it has already been stated, the answer can be found on Unix & Linux Stack Exchange:

This shows that user "saml" is a member of the wheel group.

$ getent group wheel
wheel:x:10:saml

The only difference is that the group in Ubuntu is not wheel, but sudo (or admin in older versions of Ubuntu). So the command becomes:

getent group sudo
  • What do these numbers mean? I did geten group and I see a lot of different numbers. My original question is, how to find out if a user is a system user (created with useradd -r) – Shayan Sep 21 '19 at 17:29
9

Command:

cat /etc/group | grep sudo

Output:

sudo:x:27:Tom,Stacy

Tom, Stacy are the users with sudo privileges.

Eliah Kagan
  • 117,780
XYZ
  • 91
3

On most Unix-like systems, that have the sudo command, and have a sudo configuration file; running visudo as root:

:~$ sudo bash

or

:~$ su

:~# visudo

will allow an administrator to inspect and amend the privileges of groups that can use the sudo command.

On Debian based Unix-like systems, like Ubuntu, the groups 4 and 27 generally have access rights to the sudo privileges.

Group 4 is the administrator group (adm) and group 27 is the sudo gid.

To see what users are currently assigned to these groups cat the /etc/group file as shown below:

:~$ cat /etc/group

A sample output, on Ubuntu (but not Redhat based, Oracle Solaris/Solaris based, or BSD based systems) would yield this:

adm:x:4:youruser
tty:x:5:
disk:x:6:
lp:x:7:
mail:x:8:
news:x:9: 
uucp:x:10:
man:x:12:
proxy:x:13:
kmem:x:15:
dialout:x:20:
fax:x:21:
voice:x:22:
cdrom:x:24:youruser,mybrother
floppy:x:25:
tape:x:26:
sudo:x:27:youruser,mybrother

As we can tell, youruser is the administrator of the system, and member of group 4 (adm). But youruser and mybrother are both members of group 27, which is the gid (group identification) number of group sudo. So mybrother can also attain root privileges (super user).

Many linux systems like Fedora and Slackware, incorporate the wheel group gid=10. Which allows administrator privileges when the sudo command is applied. On BSD based systems (e.g. FreeBSD), the root user is a member of the wheel group which is gid 0.

Also by using the id command any user can find the group information of another known user to the system.

For Example:

:~$ id mybrother

Sample output

uid=1001(mybrother) gid=1001(mybrother) groups=1001(mybrother),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare)
oOpSgEo
  • 539
1

I was stumped about how the vagrant user can use sudo even without being mentioned in /etc/sudoers nor in /etc/group nor found with getent.

Turns out sudo also reads entries from all files under /etc/sudoers.d/. So if you haven't looked through that directory, you may not realize how many users actually have sudo access.

This kind of sudo access can be detected by JoKeR's answer using sudo -l -U vagrant but is not detected by any of the other answers here which all rely on either getent or /etc/group.

krubo
  • 949
  • 1
    It is worth noting that the reason for this is these lines in the config file (/etc/sudoers):

    #includedir /etc/sudoers.d

    – tetra Jan 28 '20 at 12:37
1

This command returns a list of users with sudo rights:

awk -F ":" '{ system("groups " $1 " | grep -P \"[[:space:]]sudo([[:space:]]|$)\"") }' /etc/passwd

Output is (e.g.):

<username> : <username> adm cdrom sudo dip plugdev lpadmin sambashare docker

If only the user name to be displayed, then this command:

awk -F ":" '{ system("groups " $1 " | grep -P \"[[:space:]]sudo([[:space:]]|$)\"") }' | awk -F ":" '{ print $1 }' /etc/passwd
muru
  • 197,895
  • 55
  • 485
  • 740
A.B.
  • 90,397
0

Based on answers from @muru and @kos, but with some optimizations.

The getent group sudo command lists only users who have the sudo group. The rest of the commands test whether the user is actually capable of running as root. There are also other additions to improve the formatting of the output.

COMMAND

if [ -z $(getent group sudo) ]; then printf "\n >>>>>>>>>>> NO ENTRIES <<<<<<<<<<<\n\n"; 
else getent group sudo | 
sed 's/.*://' | 
sed 's/,/\n/g' | 
xargs -L1 sudo -l -U | 
grep -v 'not allowed' | 
sed 's/Matching Defaults entries/\n >>>>>>>>>>> CAN RUN COMMANDS AS ROOT >>>>>>>>>>>\n\nMatching Defaults entries/g' | 
sed '$a\\'; fi

OUTPUT

 >>>>>>>>>>> CAN RUN COMMANDS AS ROOT >>>>>>>>>>>

Matching Defaults entries for may_user_i on localhost:
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User may_user_i may run the following commands on localhost:
    (ALL) ALL
    (ALL) ALL

 >>>>>>>>>>> CAN RUN COMMANDS AS ROOT >>>>>>>>>>>

Matching Defaults entries for may_user_ii on localhost:
    !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin

User may_user_ii may run the following commands on localhost:
    (ALL) ALL

Thanks! =D

[Refs.: https://askubuntu.com/a/611607/134723 , https://askubuntu.com/a/611646/134723 , https://unix.stackexchange.com/a/136798/61742 , https://unix.stackexchange.com/a/26639/61742 ]