Table of Contents
How to check if a normal user has sudo access? Is it possible to know if a user has sudo access using a script? The script prompts for user password if I attempt to use or verify sudo privilege, can it be done without password prompt?
The other day I was writing a script which demanded a normal user to use sudo access to perform certain operation. But then I realised a normal user does not has privilege to read
sudoers file as it is only readable by root user by default
# ls -l /etc/sudoers -r--r----- 1 root root 4367 Jul 11 11:14 /etc/sudoers
So this means we cannot use grep by a normal user as it would give "
[deepak@client root]$ grep deepak /etc/sudoers grep: /etc/sudoers: Permission denied
Check sudo access as normal user
There are couple of methods you can use to check sudo access inside a script or even without a script. In this tutorial I will share the ones which I know, you can add any more to this list using the comment section. We will analyse the pros and cons of individual method so you can select the most suitable one based on your requirement.
Method 1: Using sudo -l or --list
As per the man page, sudo can be used with
--list to get the list of allowed and forbidden commands for any particular user.
The syntax would be:
sudo -l [-AknS] [-a type] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
If we use
sudo --list without any arguments, then it will print the list of allowed and forbidden commands for the user who is executing the sudo command
# sudo --list <Output trimmed> User root may run the following commands on client: (ALL) ALL
Similarly to verify for normal user, for example I have a user deepak
# sudo -l -U deepak <Output trimmed> User deepak may run the following commands on client: (ALL) NOPASSWD: /bin/chmod, !/usr/bin/passwd
deepak is allowed to use
chmod and is forbidden to use
Or you can run this as a normal user:
[deepak@client ~]$ sudo -l <Output trimmed> User deepak may run the following commands on client: (ALL) NOPASSWD: /bin/chmod, !/usr/bin/passwd
To get more detailed output of the commands allowed/dis-allowed by user, you can add
-l multiple times
[amit@client ~]$ sudo -ll Sudoers entry: RunAsUsers: ALL Options: !authenticate Commands: /bin/chown
You can also search for the exact command to make sure the provided command is allowed or not for the user
[deepak@client ~]$ sudo --list chmod /bin/chmod
So we know the user has
sudo access to use
chmod command, similarly let's try to check for a different command:
[deepak@client ~]$ sudo --list passwd [deepak@client ~]$ echo $? 1
Here the exit status is non-zero so we know that user
deepak has no
sudo access to use
If the user
deepak does not has sudo privilege, you will end up with a password prompt. Once you prove the password you would get something like below:
[deepak@client ~]$ sudo -l [sudo] password for deepak: Sorry, user deepak may not run sudo on client.
The downside of using
sudo --list is that the very first time when you execute this, it will prompt for password.
[deepak@client ~]$ sudo -l -U deepak We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for deepak:
Although you can use a workaround hack (if possible), execute
sudo --list -U <user> as
root user for the first session which will not prompt for password as the first execution is using super user and next time onward now you can use
--list with sudo even as normal user to check sudo access without any password prompt
- Get the complete list of individual commands allowed/forbidden
- Get detailed output of commands allowed/forbidden in
- Easy to use and does not depend on any other commands for execution
- Not a ideal solution for scripting as we can expect a password prompt if user has no sudo access
Method 2: Using sudo -v or --validate
sudo -v or
sudo --validate will update the user's cached credentials, authenticating the user if necessary. This is another simple approach to check sudo access but this may not give you too much detail as seen with
If the user has sudo access then this command will return zero exit status
[amit@client ~]$ sudo --validate [amit@client ~]$ echo $? 0
So we know user
amit has sudo access but he has no idea which all command are allowed/forbidden for him.
If the user has no sudo access i.e. there is no entry for a user in
/etc/sudoers then this command will return "
Sorry, user XXX may not run sudo on client."
[deepak@client ~]$ sudo --validate Sorry, user deepak may not run sudo on client.
- Ease of use
- Can be useful if the requirement is only to check presence of user in
- Can be used with scripting based on requirement
- You get no information about the list of commands allowed/forbidden for the individual user
Method 3: Use sudo with timeout
If you just attempt to use sudo for any command as normal user, the downside is the password prompt (assuming user has no sudo access). If the user has sudo access for the provided command with
NOPASSWD argument then there is no problem at all. But in scripts we have to handle both positive and negative scenarios.
So we must also handle a possible scenario that the script may get stuck waiting for user password prompt with sudo. So how do we handle this? timeout to the reuse
In bash we have timeout utility which is used to kill stuck processes and moreover timeout also can be used to kill itself if for some reason timeout also gets stuck.
So assuming the user
deepak was expecting, he has sudo privilege for using
chmod command and he tries to use
chmod from within the script
[deepak@client ~]$ sudo chmod --help [sudo] password for deepak:
The script halts waiting for user input. So we add
timeout with this command, to monitor the time of execution I have also added "
[deepak@client ~]$ time timeout 2 sudo chmod --help [sudo] password for deepak: real 0m2.011s user 0m0.015s sys 0m0.009s [deepak@client ~]$ echo $? 124
So as expected after waiting for 2 seconds, the
sudo prompt was killed. If the command times out, and
--preserve-status is not set, then exit with status 124. You can use
--preserve-status to exit with your command's exit status
So we can use this within our script and send the output to
/dev/null or to any of your log file to avoid any unwanted messages on the console. I had to use
timeout as I observed that timeout was stuck infinitely within the shell script.
#!/bin/bash timeout -k 2 2 bash -c "sudo chmod --help" >&/dev/null 2>&1 if [ $? -eq 0 ];then echo "yay, user `id -Gn` has sudo access" else echo "sorry, user `id -Gn` has no sudo access" fi
If we execute this script, the output
[deepak@client ~]$ /tmp/script.sh /tmp/script.sh: line 3: 2299 Killed timeout -k 2 2 bash -c "sudo chmod --help" &> /dev/null 2>&1 sorry, user deepak has no sudo access
It does the work but clearly the output is not good, so let's fix this by sending output to
#!/bin/bash `timeout -k 2 2 bash -c "sudo /bin/chmod --help" >&/dev/null 2>&1` >/dev/null 2>&1 if [ $? -eq 0 ];then echo "yay, user `id -Gn` has sudo access" else echo "sorry, user `id -Gn` has no sudo access" fi
Now we execute this script:
[deepak@client ~]$ /tmp/script.sh sorry, user deepak has no sudo access
So now we can check the sudo access with cleaner output on the console. You can also assign a variable based on the execution and then use the variable in your script.
#!/bin/bash has_sudo_access="" `timeout -k 2 2 bash -c "sudo /bin/chmod --help" >&/dev/null 2>&1` >/dev/null 2>&1 if [ $? -eq 0 ];then has_sudo_access="YES" else has_sudo_access="NO" fi echo "Does user `id -Gn` has sudo access?: $has_sudo_access"
Now assuming I have added sudo access for user
/bin/chmod, let's execute this script:
[deepak@client ~]$ /tmp/script.sh Does user deepak has sudo access?: YES
- Can be used in a script to check sudo access for normal user in Linux
- Can return user defined exit status or variables based on the condition match
- The solution is not very robust, as if a switch user is done without using hyphen (
-), it is possible this command may fail because proper
PATHvariables are not found
- If exact path is not used for the commands, for example here
/bin/chmod, if I just use
chmodthen this will not give correct exit status. So the command must match with what is there in
- Dependency with
timeoutalso must be installed on the server.
Method 4: Using sudo with -S or --stdin
You can use
-S to write the prompt to the standard error and read the password from the standard input instead of using the terminal device. The password must be followed by a newline character.
For example, in this sample script I am providing password for my user "
deepak" to check the sudo access
#!/bin/bash has_sudo_access="" printf "mypassword\n" | sudo -S /bin/chmod --help >/dev/null 2>&1 if [ $? -eq 0 ];then has_sudo_access="YES" else has_sudo_access="NO" fi echo "Does user `id -Gn` has sudo access?: $has_sudo_access"
If the user has
sudo access to execute
/bin/chmod, the output would be:
Does user deepak has sudo access?: YES
Or else you will get:
Does user deepak has sudo access?: NO
- Easy solution to check
sudoaccess for individual commands
- Can be easily used in scripts
- Not good for security as you have to provide your user's password in plain text format within the script. Although you can use third part tools to encrypt your script or convert it into binary format so no one can read your script content.
In this tutorial we learned about different possible solutions to check
sudo access using normal user in Linux. You may choose the most appropriate solution based on your requirement. Please note you may have to use "
sudo -K" or "
sudo --remove-timestamp" to remove the user's cached credentials entirely from the user session. As once the user's
sudo is modified, it is possible the user will still have the access based on earlier permission unless you refresh the cache.
Lastly I hope the steps from this tutorial to check Linux sudo access as normal user was helpful. So, let me know your suggestions and feedback using the comment section.