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 certainoperation. 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
“Permission denied”
[deepak@client root]$ grep deepak /etc/sudoers
grep: /etc/sudoers: Permission denied
Before you go ahead, make sure you verify the group membership of your user. It is possible sometimes the user os part of some admin or wheel group which by default gives the user all kind of sudo privilege even though your sudoers may not contain any entry for this user. For exmaple, in this case user deepak is part of wheel group so by default he will get all sudo privilege as applicable for root user.
[root@client ~]# id deepak
uid=1001(deepak) gid=1001(deepak) groups=1001(deepak),10(wheel)
So to treat him as a normal user we must remove this user from wheel group.
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 -l or --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
So user deepak is allowed to use chmod and is forbidden to use
passwd with sudo
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 passwd command
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
Pros
- Get the complete list of individual commands allowed/forbidden
- Get detailed output of commands allowed/forbidden in
sudoerslist - Easy to use and does not depend on any other commands for execution
Cons
- 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 sudo --list
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.
Pros
- Ease of use
- Can be useful if the requirement is only to check presence of user in
/etc/sudoers - Can be used with scripting based on requirement
Cons
- 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 “time”
[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
Example Script
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 -k with 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 /dev/null
#!/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 deepak for
/bin/chmod, let’s execute this script:
[deepak@client ~]$ /tmp/script.sh
Does user deepak has sudo access?: YES
Pros
- 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
Cons
- The solution is not very robust, as if a switch user is done without
using hyphen (
-), it is possible this command may fail because properPATHvariables are not found - If exact path is not used for the commands, for example here
/bin/chmod, if I just usechmodthen this will not give correct exit status. So the command must match with what is there insudoerslist - Dependency with
timeoututility, sotimeoutalso must be installed on the server.
Method 4: Using sudo with -S or –stdin
You can use sudo with --stdin or -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.
Example Script
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
Pros
- Easy solution to check
sudoaccess for individual commands - Can be easily used in scripts
Cons
- 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.
Conclusion
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.


