How can I tell if I have permission to run a particular command?

Solution 1:

The simplest case is that of a binary executable like gzip. First, we locate the executable:

$ which gzip
/bin/gzip

Then we look at the attributes of this file:

$ ls -l /bin/gzip
-rwxr-xr-x 1 root root 98240 oct 27  2014 /bin/gzip

The three x's tell us that the file may be executed by the owner (the first root), or anyone in the group root (second root) and anyone else, respectively. So your user is allowed to execute the program.

However, your executable may be a script file that calls other executables inside. You may be able to execute the script but not the programs called inside of it. There is no way to determine if your user is allowed to do that, other than actually trying it out.

Then there are special cases like shutdown - this is really a symbolic link to a core utility called systemctl, which has its own mechanisms to determine whether you are allowed to call it, and to ask you for your sudo password if you don't, for instance.

(About the which command: this locates executables in your $PATH that you are allowed to execute, and tells you which one you use if you have more than one with the same name in the $PATH. It does not locate just any executable. I use it here as an example of where to look for the permission. The fact that which finds the executable already indicates that you have permission to execute it.)

Solution 2:

With sudo:

$ sudo -l shutdown
/sbin/shutdown

If I didn't have permission, sudo will complain instead of showing the command.

With polkit, you check for the action you want to run:

$ pkcheck --action-id org.freedesktop.login1.power-off --process $$ -u --enable-internal-agent && echo yes
polkit\56temporary_authorization_id=tmpauthz1
yes

Finding the relevant action is a different question.

Solution 3:

You can use:

test -x $(command -v shutdown) && echo yes || echo no

command -v shutdown returns the path to the shutdown command. test -x checks if that path is executable to you.

Note that though you might be able to execute the command, the command may still fail because it has inadequate permission to carry out the task. This is the common case on Unix-type systems, which rather than restricting access to execute a command, instead restrict access on the operations that programs can actually do.

Solution 4:

Well it can be a bit difficult at times...

First of all, look at the permissions with ls -l...

 owngrpotr  user  group  command
-rwxr-xr-x  root  bin    vim

If the last/third triplet got an x ("can execute") in it, then others - and that means you - can execute it... If it's a shell-script or something like that, then others would need r ("can read") too.

If others don't got execute-permission but group (the second triplet) does, then you can execute it if you're a member of the group - in the example over, bin. For example, the wheel-group is often used to limit who may run su, so only users belonging to this group could execute it at all. Another example is making a group for developers, and restrict execution of the C-compiler and such tools to this group.

If there is a trailing + after the last triplet, that means that AccessControllLists are used - this may add execution-rights to additional users and groups.

+++

Even if you are able to execute the command, the command may depend on access to files, directories and/or devices that you don't have access to - this may limit what you'll be able to do (you may not be able to do anything).

Finally although you may be allowed to execute a command, the command itself may check your identity, and refuse to let you use it unless you're listed in a config-file or is certain users (eg. root). For example the mount command will only allow root to mount any device - normal users are only allowed to mount devices listed as such in /etc/fstab... which may be none. If you're not root and tries to mount something, mount will complain and refuse to mount the device. Another example is sudo, which will run for anybody, but only users listed in /etc/sudoers will actually be allowed to run things as root.

Solution 5:

Using which, type, command etc. is a practical solution which will work in 99% of the cases, but to be 100% sure you'll have to manually inspect every executable directory listed in your $PATH. Many shells (including bash) will prefix your command with entres from $PATH and try to execute those files repeatedly until they succeed. Since which cannot really execute the command, it's impossible for it to predict which file your shell will really pick.

For example, imagine I have PATH=/opt/arm/bin:/bin, both directories containing executable files, but for different architectures. Running which dd will return /opt/arm/bin/dd (assuming I have permissions to execute it), since that entry comes first. However, when I run dd in my shell, /bin/dd will be executed, because /opt/arm/bin/dd will fail to run. The same situation may happen in case of corrupt binaries, missing libs, etc. In the end, there's no sure way to know whether you will be able to execute a command or not, aside from trying.

Another aspect is what you consider "having permissions". As a user, I do have permissions to run rm ~/file but not rm /root/file. Again, there's no general way to know that without manual inspection, or issuing the command and observing the results.