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 '13 at 7:05
  • hmm that's correct , so is there anyway ? – Rahul Patil Sep 17 '13 at 7:07
  • also user don't need to compile he can easily copy cp /bin/mkdir mkdir2 then use it :( – Rahul Patil Sep 17 '13 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. – G-Man Says 'Reinstate Monica' Aug 21 '15 at 7:19

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
| improve this answer | |
  • 3
    with allowed = 'all' - ['mkdir'], can't you just execute bash and be unrestricted again? – dawud Sep 17 '13 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 '13 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 '13 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 '13 at 13:01
  • 2
    @dawud It does, indeed. I missed the read-only bin directory. – Marco Sep 17 '13 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.

| improve this answer | |

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.

| improve this answer | |
  • 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 '13 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 ? – Rahul Patil Sep 17 '13 at 7:20
  • 1
    @RahulPatil yes, and of course you need to restrict their use of a compiler as well. – peterph Sep 17 '13 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

| improve this answer | |
  • /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 ==). – Stéphane Chazelas Apr 21 '16 at 15:23

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

| improve this answer | |
  • 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 '13 at 12:21
  • This answer is just plainly wrong – kiltek Mar 8 '18 at 9:26

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.