I know how to restrict standard users to run a command by removing execute permissions for that command. But it's possible restrict standard users to run a command with a specific option/argument?

For example a standard user should be able to run the following command:


but not:

ls -l

I think that this can be possible since there are some commands like chsh or passwd which a standard user can run them, but he get permission denied when he runs chsh root or passwd -a -S.


I think the only way would be to write your own wrapper to the command/utility in question and have it decide what is allowed or not allowed based on the (E)UID of the user who started it. The tools you mention that do this such as chsh or passwd have this functionality built into their implementation.

How to write a wrapper for ls


use strict;
use warnings;

my $problematic_uid = 1000; # For example
my $is_problematic = $< == $problematic_uid;
unless(/ -l / ~~ @ARGV or $is_problematic){
    exec qq{/new/path/to/ls }.join '',@ARGV
    die "Sorry, you are not allowed to use the -l option to ls\n"

You need to ensure that the path to the original ls isn't in your user's PATH. Which is why I wrote /new/path/to/ls. The problem is, this wrapper requires that your user be able to execute the original ls so the user may still circumvent it by calling the original ls directly.

  • @RaduRădeanu Sure. Give me a few minutes to skim through man sudoers and post back here. I know that this is possible from a previous reading of the page but I forgot the mechanics of it. – Joseph R. Sep 23 '13 at 20:35
  • @RaduRădeanu It seems this won't work for your use case. The sudoers page says if you specify command line arguments then this is the only version of the command the user is allowed to run through sudo, which is different to what you want. My bad... – Joseph R. Sep 23 '13 at 20:43
  • I was thinking about that, also... But, what about write your own wrapper to the command...? How can I do this? Sincerely is first time when I hear about something like this. – Radu Rădeanu Sep 23 '13 at 20:48
  • @JosephR. you would have to specify all possible combinations of the options. While this looks impossible fo commands like ls, tar or ps, it could work with a subset of options, if they are at least sorted in a wrapper. – peterph Sep 23 '13 at 20:55
  • @RaduRădeanu wrapper is a simple executable (usually in a scripted language) that (often) has the same name as the target executable, but precedes it during command lookup (e.g. it is in a directory, that appears in PATH earlier than the target). In your case however, this is quite problematic, since you don't want to allow access to the target executable - yet it has to be accessible to the wrapper. – peterph Sep 23 '13 at 20:59

Commands like chsh and passwd are coded specially. They run with extra privileges (they're setuid) root) and contain their own authorization mechanism. Both check which user is invoking them, and allow non-root users only a subset of their functionality.

chsh and passwd are the exception. Most commands don't care who invokes them.

Forbidding users from running one particular command is pointless: they can do whatever that command does in some other way, such as by supplying their own executable.

You can make a restricted account that is only allowed to run a whitelisted set of commands: with a restricted shell, or for data-transfer-only accounts, rssh or scponly.

If you want to allow a user to run a certain command with elevated privileges (typically via sudo), but only for certain combinations of options, then write a wrapper script that checks the options and allow the user to run that wrapper script.


Rahul's answer is relevant to your question, because what you want is a) not a good idea and b) probably only possible by creating a custom shell. Executables like ls are separate, stand-alone programs that handle their arguments by themselves - if you'd want to prevent users from using ls -l, you would have to write and compile your own custom ls. As you can probably imagine, that would not be easy and it would also take a lot of time, because you have to do that for every single command that you want to change.

You could maybe try to replace the whole shell (in your case probably bash) completely with a different shell that filters the commands of your users. For example, it could try to remove the -l from ls command lines before actually calling ls. This isn't as easy as it sounds though, because shells and also the commands that you can run from a shell usually have a very powerful and complex syntax, and trying to filter that will probably leave holes and break stuff.

I think that this can be possible since there are some commands like chsh or passwd which a standard user can run them, but he get permission denied when he runs chsh root or passwd -a -S.

That's something else entirely, because these programs are written that way. If you'd want to change their behaviour just as you want to change the behaviour of ls, you would have to modify their source codes and recompile them.

  • It wouldn't be that difficult, since removing an option is much easier than adding one (usually you just need to comment out a couple of lines of code). – peterph Sep 23 '13 at 21:02
  • Still, it sounds like an insanely bad idea to me, just like "hey, let's disable the desktop icons and the command prompt on the Windows workstations of our users, cause you know, that stuff is DANGEROUS". I really dislike that approach. – Martin von Wittich Sep 23 '13 at 21:24
  • Well, restricting access to a narrow set commands definitely makes sense under some circumstances. Restricting use of some options for ls and similar sounds like quite a silly idea indeed (the example of ls is definitely a bad one). But for some commands it might make sense as well - c.f. unix.stackexchange.com/questions/91214/… – peterph Sep 24 '13 at 8:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.