5

I want to run a specific command, such as rm, while logged in as root, but I want the root password prompt to be shown every time. When I run su -c "command" as root, I was not prompted for a password.

terdon
  • 100,812
Ayaan
  • 67
  • 10
    I don't understand. If you're logged in as root, you already have maximum rights. If you want to be prompted, don't log in as root. – terdon Mar 01 '17 at 11:28
  • 1
    is there any way to do that.i just want it so if anyone use my terminal he won't be able to use rm. – Ayaan Mar 01 '17 at 11:32
  • I don't know if that is possible but one possible measure maybe this: http://askubuntu.com/questions/636092/how-to-get-sudo-to-prompt-you-for-a-password-each-time – Diogo Vilela Mar 01 '17 at 11:37
  • 3
    Limiting just some commands is not smart, there are so many ways how they can damage the system with root privileges or make their user priviledged. Just use common security sense and either lock terminal when you leave or logoff root. – marosg Mar 01 '17 at 11:39
  • 4
    @userx that's pointless. If you leave a terminal with root access open, your system can be destroyed without ever needing to use rm. They can format your disks, for example. Or use mv or cp instead of rm (e.g. cp emptyFile targetFile which will leave targetFile there, unlike rm, but make it empty). Or they could just run > targetFile to empty the file. Or they could run find / -delete. There are dozens of ways they can hurt your system without having access to rm. – terdon Mar 01 '17 at 11:42
  • its just not about rm, i just want to know if there is any way to do it or not ? – Ayaan Mar 01 '17 at 11:48
  • 5
    @userx But why? It is REALLY BAD to leave your computer unlocked with a terminal open, and REALLY BAD to use root terminals. Combining these two makes your system catastrophically insecure. Do not regularly use root terminals unless you're doing a LOT of low-level administration in one go (I maybe open a root terminal twice a year, always in the safety of my own home, and even then I feel very uncomfortable while doing it), and do not walk away from your computer without locking it. – Muzer Mar 01 '17 at 13:36
  • how about creating a non root user account and then just using su when necessary? Surely this is the better solution - especially if you are worried about other users? It's also better from a procedure / accounting point of view - so you can log individual user actions rather than everything under root. Also useful to set a timeout for ssh so it logs out after a while of inactivity. – Jeff Mar 01 '17 at 17:14

3 Answers3

10

Specifically for su, root is not prompted for a password because su's PAM rules allow it:

$ grep root /etc/pam.d/su
# This allows root to su without passwords (normal operation)
auth       sufficient pam_rootok.so
# Uncomment this to force users to be a member of group root
# than the default "root" (but this may have side effect of
# denying "root" user, unless she's a member of "foo" or explicitly
# permitted earlier by e.g. "sufficient pam_rootok.so").

If you want to make su ask for a password for root, comment out the use of pam_rootok. Of course, su doesn't care for commands, so any use of su by root will then ask for the password.

You can't protect individual commands from root without risking a lot of breakage. Just lock your terminal when you leave it. Don't run root sessions.

muru
  • 197,895
  • 55
  • 485
  • 740
  • 1
    Might this break a lot of things? Are there scripts that run as root that use su to switch to a different user to run commands? – Muzer Mar 01 '17 at 13:38
  • @Muzer why should they be using su? sudo is, afaic, the better way to run commands. – muru Mar 01 '17 at 13:49
  • You can't use sudo in an unattended script to switch from root to some other user. I'm thinking of the sort of thing you'd put in /etc/rc.local that launches something as a non-root user. – Muzer Mar 01 '17 at 13:52
  • @Muzer sudo -u user foo? – muru Mar 01 '17 at 13:52
  • Hmm, TIL. I guess it's not very compatible with UNIX installations that don't use sudo, though, so I'd probably prefer using su especially if I were writing a multi-platform script to be distributed. – Muzer Mar 01 '17 at 13:54
  • @Muzer how many of those use PAM? – muru Mar 01 '17 at 14:09
  • If you make a script that's supposed to run on most UNIX installations you throw it at, and then someone who's made a silly modification to Ubuntu like disabling passwordless 'su'ing to other users for root tries to run it, it won't work. – Muzer Mar 01 '17 at 14:13
  • 1
    To be clear, this probably has its uses - for a deliberately very locked-down system that needs to have a very strict security policy - but OP's use case I don't think is this at all. This is a massively incompatible and breaking change that doesn't really solve any immediately obvious problem of OP's. Of course, if I'm wrong and this really is what OP needs, I apologise. I just think that with the information we have at the moment, the whole endeavour is very misguided. – Muzer Mar 01 '17 at 14:28
  • 1
    @Muzer no security policy is going to beat a user who leaves their terminal unlocked with root sessions active. I agree that the whole endeavour is misguided, but unfortunately, this post was reopened after I'd closed it against a post which explains how misguided. And if you're administering systems with users like that, you should be more worried about the users than scripts breaking because of silly rules like this. – muru Mar 01 '17 at 14:32
  • I completely agree with you on that point! – Muzer Mar 01 '17 at 14:43
8

You can use this code for rm wrapper script but you might want to create similar versions for mv and find as well.


Edit Mar 5 2017 - Change method of checking when running in terminal.


This answer checks if running at the terminal and does not prompt for password if running in a background script such as startup, cron or GUI. The script can be improved to ensure rm was typed directly in the terminal. Then if another script like sudo update-grub or sudo apt update called rm a second password would not be required.

I've written a script to password protect rm like the OP requested and the code below is the same except it demands password from sudo / root user. It also has edits to prevent you from accidentally deleting:

  • /
  • /home
  • /bin

Create the script

Use gksu gedit /usr/local/bin/rm and copy in these lines:

#!/bin/bash

tty -s;
if [ "0" == "$?" ]; then Terminal="Y"; else Terminal="N"; fi

if [ $Terminal == "Y" ] ; then    

    # Running from terminal don't allow delete of / or /toplevel directory even if sudo
    for i in ${@:1}
    do
        # Skip options -i -r -v -d 
        if [[ ${i:0:1} != "-" ]] ; then
            # if parameter doesn't begin with '-' it's file or directory, so get real path.
            fullname=$(realpath "$i" 2>&1) # No error messages if file doens't exist
            # We must have at least two `/` in the full path
            levels=$(echo "$fullname" | tr -cd '/' | wc -c)
            if (( $levels == 1 )); then # Test for 1, will be zero when file doesn't exist.
                echo "Attempting to remove top level directory '$fullname'"
                echo "Use 'sudo /bin/rm $@' instead."
                exit 1 # error
            fi
        fi
    done
fi


if [ $Terminal == "Y" ] ; then    
# Only running from a terminal needs password (ie not cron)

    # log rm usage to /var/log/syslog
    PARENT_COMMAND="$(ps -o comm= $PPID)"   
    logger "$PARENT_COMMAND"" - rm command was used on file: ""$fullname"

    # Get password
    Password=$(zenity --password --title="Password for rm")
    encryptPassword=$(echo -n "$Password" | md5sum)

echo "md5sum: $encryptPassword" # Comment out after viewing one time and updating line below.

    if [[ "$encryptPassword" != "d2c30dc65e59558c852ea30b7338abbe  -" ]]; then
        echo "Invalid password!"
        exit 1
    fi

fi # non-terminals can't enter password.

# Call REAL rm command with parameters passed to this wrapper sript
/bin/rm "$@"

exit 0

Change the password "WE2U" to anything you like and save the file.

Mark new rm script as executable

Flag new rm script as executable using:

sudo chmod +x /usr/local/bin/rm

How it Works

rm password

Unless the password is WE2U, the first time you run the script you will get "invalid password" and the encryption key for the password you entered is displayed. Copy and paste this encryption key from the terminal into the script. Then comment out the line with the echo that displayed the encryption key on the terminal.

Because the path /usr/local/bin is higher on the list than /bin our command rm is called. After getting valid password it calls /bin/rm to do the real removal.

The script calls logger to record every time rm was manually called using the terminal. Command usage is recorded to /var/log/syslog.

Taken from the answer posted at (How can I set up a password for the 'rm' command?) and modified to demand password from root user too.

  • /usr/bin/rm - i win. \o/; – djsmiley2kStaysInside Mar 02 '17 at 00:48
  • find / --delete --name file - I win again... – djsmiley2kStaysInside Mar 02 '17 at 00:49
  • @djsmiley2k I noticed in your profile you like to play games. In Q&A there isn't much gaming and you don't "win" anything. The OP requested and answer and one was delivered. You can post your own answer even if it says "it can't be done" or "it shouldn't be done because ____". Taunting or mocking me is a futile endeavor. – WinEunuuchs2Unix Mar 02 '17 at 01:02
  • 1
    I wasn't meant to be mocking, it was showing the futileness of the entire exercise. – djsmiley2kStaysInside Mar 02 '17 at 01:12
  • The initial incarnation was to rename /bin/rm to something else like /bin/del and but the wrapper script into /bin/rm but others weren't comfortable with that so I changed it to be in /usr/local/bin/rm. That would take away your first "win" by reverting to original design. As far as find goes that can be wrapped along with mv and maybe I'll do that some day. I've already written a wrapper for dd to prevent erasure of hard disk too. The point here is to answer a given question, not to give all the answers possible for all similar situations. – WinEunuuchs2Unix Mar 02 '17 at 01:16
0

The simplest solution I can think of is to su to a different user and then back to root again:

su userx -c 'su -c "ls"'

One drawback of this is that if you need special characters in the command, the escaping becomes tricky.

kasperd
  • 1,729