How to block command, let say mkdir for specific user ?

What I did just created read-only function and store in users profile ~/.bashrc

/bin/mkdir() {
        echo "mkdir command not allow for you"


mkdir() {
        echo "mkdir command not allow for you"

./mkdir() {

        echo "mkdir command not allow for you"

readonly -f /bin/mkdir
readonly -f mkdir
readonly -f ./mkdir


rahul@ubuntu:~$ cd /bin/
rahul@ubuntu:/bin$ ./mkdir /home/rahul/ggg
mkdir command not allow for you
rahul@ubuntu:/bin$ cd
rahul@ubuntu:~$ mkdir testing
mkdir command not allow for you
rahul@ubuntu:~$ /bin/mkdir testing
mkdir command not allow for you

So my question is What should be the way of achieving this ? is there any tool for this ?

Update 1 # But if user is smart , he could copy mkdir binary and rename it and use it . So how to achieve this ?

  • 7
    Your example will fail because the user could compile his own mkdir and rename it, or even just copy and rename the existing binary. Also, there's a shell builtin for overriding aliases and functions.
    – strugee
    Sep 17, 2013 at 7:05
  • hmm that's correct , so is there anyway ? Sep 17, 2013 at 7:07
  • also user don't need to compile he can easily copy cp /bin/mkdir mkdir2 then use it :( Sep 17, 2013 at 7:08
  • Creating a directory is such a common/fundamental task that there are multiple ways of doing it, and it would be almost impossible to block them all (except by not letting the user create files; i.e., write-protecting all directories against him).  For example, cp -r /usr/local/lib ggg will create a directory called ggg (containing a copy of the contents of /usr/local/lib, if any, which the user can then just delete).  You can use find / -type d -empty to find an empty directory to copy. Aug 21, 2015 at 7:19

5 Answers 5


I don't know how to do it with bash, but I know of another shell that restricts the user environment: lshell (limited shell).

A quick overview of configuration

Lshell is configured via an INI file. By default, it holds a whitelist of allowed commands, but it can be easily configured to prohibit user from using a specific command.

This configuration (default conf /etc/lshell.conf) prohibits user foo from using mkdir:

allowed = 'all' - ['mkdir', 'bash', 'sh', 'csh', 'dash', 'env']

In order to configure a user account to use lshell by default, you must:

 chsh -s /usr/bin/lshell foo

Lshell can do more, like:

  • 3 levels of granularity: user, group, all.
  • Can restrict access to certain paths in the system.
  • Can restrict the use of certain characters (like |).
  • Can restrict the use of certain commands only over SSH.

And more.

Update 1# Added Test Result :

rahul:~$ which bash
rahul:~$ dd if=$(which bash) of=my_bash
*** forbidden syntax: dd if=$(which bash) of=my_bash
rahul:~$ bash
*** forbidden command: bash
rahul:~$ cp /bin/bash my_bash
*** forbidden path: /bin/bash
rahul:~$ /bin/bash
*** forbidden command: /bin/bash
rahul:~$ sh
*** forbidden command: sh
rahul:~$ dash
*** forbidden command: dash
rahul:~$ env bash
*** forbidden command: env
rahul:~$ cp /bin/mkdir mycreatedir
*** forbidden path: /bin/mkdir
  • 3
    with allowed = 'all' - ['mkdir'], can't you just execute bash and be unrestricted again?
    – dawud
    Sep 17, 2013 at 7:54
  • 3
    Just being pedantic, sorry, but there are still a lot of ways to circumvent the restrictions imposed by that list, e.g. dd if=$(which bash) of=my_bash && chmod u+x my_bash && ./my_bash. I think the problem is the lack of a restrictive default policy, i.e., in this scenario you GRANT permissions by default, then DENY permissions based on a list, when it should be the other way around: DENY by default, then GRANT based on policy.
    – dawud
    Sep 17, 2013 at 8:48
  • 1
    @dawud: I agree that maintaining a whitelist of allowed commands is a better approach than having a blacklist and hoping the user won't circumvent it by out-clevering the admin.
    – rahmu
    Sep 17, 2013 at 9:19
  • 2
    @Marco, check the example provided in my answer. I provide a whitelist of allowed commands, and in that scenario, the user cannot just cp a binary to his/her PATH (root owned directory, rx for the user), and rbash prevents from executing ./executables. Does it answer your question?
    – dawud
    Sep 17, 2013 at 13:01
  • 2
    @dawud It does, indeed. I missed the read-only bin directory.
    – Marco
    Sep 17, 2013 at 13:05

The way I usually implement this kind of restrictions requires that several conditions are met, otherwise the restriction can be easily circumvented:

  • The user does not belong to the wheel group, the only one authorized to use su (enforced via PAM).
  • The user is given a properly secured rbash with a read-only PATH pointing to a private ~/bin, this ~/bin/ directory contains links to simple utilities:

    $ ll ~/bin
    total 0
    lrwxrwxrwx. 1 root dawud 14 Sep 17 08:58 clear -> /usr/bin/clear*
    lrwxrwxrwx. 1 root dawud  7 Sep 17 08:58 df -> /bin/df*
    lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 egrep -> /bin/egrep*
    lrwxrwxrwx. 1 root dawud  8 Sep 17 08:58 env -> /bin/env*
    lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 fgrep -> /bin/fgrep*
    lrwxrwxrwx. 1 root dawud  9 Sep 17 08:58 grep -> /bin/grep*
    lrwxrwxrwx. 1 root dawud 10 Sep 17 08:58 rview -> /bin/rview*
    lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 rvim -> /usr/bin/rvim*
    lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 sudo -> /usr/bin/sudo*
    lrwxrwxrwx. 1 root dawud 17 Sep 17 08:58 sudoedit -> /usr/bin/sudoedit*
    lrwxrwxrwx. 1 root dawud 13 Sep 17 08:58 tail -> /usr/bin/tail*
    lrwxrwxrwx. 1 root dawud 11 Sep 17 08:58 wc -> /usr/bin/wc*
  • the user is given a restricted, read-only environment (think of stuff like LESSSECURE, TMOUT, HISTFILE variables).

  • the user is mapped to the SELinux user staff_u and given rights to execute commands as other user as required via sudo.
  • the user's /home, /tmp and possibly /var/tmp are polyinstantiated via /etc/security/namespace.conf:

    /tmp       /tmp/.inst/tmp.inst-$USER-     tmpdir:create   root
    /var/tmp   /tmp/.inst/var-tmp.inst-$USER- tmpdir:create   root
    $HOME      $HOME/$USER.inst/              tmpdir:create   root

    Also, /etc/security/namespace.init makes all skeletal files readonly for the user and owned by root.

This way you can choose whether $USER can execute mkdir on his/her own behalf (via a link in the private ~/bin directory, provisioned via /etc/skel, as explained above), on behalf of other user (via sudo) or none at all.


Add a dummy group, add the user to that group, chown root:somegroup /bin/mkdir, chmod g-x /bin/mkdir. Note that this relies on the user not being able to modify their groups. IIRC this is true in GNU/Linux but not in some other Unices.

  • 2
    On most filesystems you can also use extended ACLs for finer grained control - the number of groups needed would grow exponentially with the number of users (due to possible combinations), not to mention the naming problems.
    – peterph
    Sep 17, 2013 at 7:19
  • 2
    add one more point, also remove read permission from other users 710, so user could not copy and rename that binary isn't it ? Sep 17, 2013 at 7:20
  • 1
    @RahulPatil yes, and of course you need to restrict their use of a compiler as well.
    – peterph
    Sep 17, 2013 at 7:21

The best as i have tested is to use Profile.d best & safest way

Step # 1 (Create a Alias File)

[root@newrbe ~]# vim /etc/customalias.sh

Add Below lines :

alias rm="echo remove contenet is restricted"
alias poweroff="echo Poweroff is restricted"
alias chmod="echo Change Permission is restristed"

Save & quit

Step # 2 (Create Profile loader)

/etc/profile.d/ this location contains files for bash completion

[root@newrbe ~]# vim /etc/profile.d/customsource.sh

Add below lines under the files these lines will block mentioned commands for below users

if [ `whoami` == "user1" ] && [ `whoami` == "user2" ]; then
    source /etc/customalias.sh

save and quit

Now Exit and relogin

Regards, -Mansur

  • /etc/profile.d/ is not for bash completion, it's where to place login session customisations for users using POSIX-like login shells, so it's typically not where bash alias customisations (which would rather go in /etc/bash.bashrc) would go and it should have a POSIX shell syntax (so typically, . instead of source and = instead of ==). Apr 21, 2016 at 15:23

install sudoers and try to configure there whose users and what command.

  • 4
    Welcome to SX. Please add details to your answer; the OP, or anyone else reading this question in the future, may not be aware of sudo.
    – Joseph R.
    Sep 18, 2013 at 12:21
  • 1
    This answer is just plainly wrong
    – kiltek
    Mar 8, 2018 at 9:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .