6

I'm writing a shell script, that needs to be run with root privileges.

I can check if a user has root privileges with sudo -nv || echo "no sudo", but that doesn't help me, if his credentials are still cached by sudo, but he didn't call my script with it. So I have no way of reacting to a user, not calling my script with sudo.

I could put sudo in front of every command that needs it, so just checking to see if the user has root privileges would be enough, but it seems to me, that there should be a better solution.

I'm looking for a command, that I can put into my script, that asks the user for root privileges and, if provided, executes the rest of the script, as if the user called it with root privileges in the first place.

What I want:

#!/bin/bash

if ! command; then        # what I'm looking for
    echo "This script needs root privileges."
    exit 1
fi

mv /bin/cmd1 /bin/cmd2    # requires root

Edited 2 times

  • If the user is running the script, and you want them to sudo every command in the script, I don't understand why they wouldn't just sudo the script. Even if you sudo every command and redirect stdout/stdin/stderr properly, the user still has to enter root credentials either way. – cremefraiche Dec 11 '14 at 14:16
  • "I'm looking for a command, that I can put into my script, that asks the user for root privileges and, if provided, executes the rest of the script," This is exactly what running the script as sudo does. Seems like reinventing the wheel. – cremefraiche Dec 11 '14 at 14:17
  • @cremefraiche If the user runs the script with sudo, that would be completely fine. What I'm looking for is a failsafe if they don't do that. Checking for root privileges like I mentioned above does not ensure, that the user called my script with sudo, just that the credentials are cached. So I'm looking for something, that runs the script as if the user called it with sudo in the event, that he forgot. – Minix Dec 11 '14 at 14:26
  • I understand now, It seemed to me that you were checking if users were sudoers to prevent malicious use, which was hard for me to understand what the problem was. I have now updated my answer to achieve this effect without causing unnecessary lines of code to be run. – cremefraiche Dec 11 '14 at 15:07
9

Test if you are root, and if not, restart with sudo, for example:

#! /bin/bash

if [[ $EUID -ne 0 ]];
then
    exec sudo /bin/bash "$0" "$@"
fi
  • I thought about something like that. But I was a bit hesitant. Are there any security concerns? Will read the man page about exec. Didn't need it until now. – Minix Dec 11 '14 at 14:54
  • @Minix it's a shell builtin. Try help exec, or look at the man page of bash or sh. I think this is safe, but I am not sure. – muru Dec 11 '14 at 14:55
  • 1
    probably want to pass the args too: exec sudo /bin/bash "$0" "$@" – glenn jackman Dec 11 '14 at 15:53
  • 1
    This is probably plenty safe on any system that interprets the #! bangline - provided the proper sudo is in $PATH. If the presumption is that the bangline is interpreted then the /bin/bash bit is not really necessary though - exec sudo "$0" "$@" should be enough - and might be beneficial in that on those POSIX systems that dont handle the bangline but still do sudo it would probably still get the original script run with escalated privileges. Where sudo is iffy, POSIX also specs the newgrp command. – mikeserv Dec 11 '14 at 18:15
  • 1
    well, the very first bullet in the shell command language spec reads: The shell reads its input from a file (see sh), from the -coption or from the system() and popen() functions defined in the System Interfaces volume of IEEE Std 1003.1-2001. If the first line of a file of shell commands starts with the characters "#!", the results are unspecified. I think that is a windows thing - POSIX is not all about unix-likes. I never tried to hunt it down, though. Thats also about what the shell itself does with it - not the kernel. POSIX doesnt tell kernels what to do, mostly. – mikeserv Dec 11 '14 at 18:31
2

I believe what you are trying to accomplish is making sure the user runs a script as root.

To do this, you do not want to add it to the script, but instead just change the ownership of the file and the execute permissions. This can be done with:

# chmod og-rx yourscript.sh
# chown root:root yourscript.sh

(by muru =])

or

# chmod 750 yourscript.sh
# chown root:root yourscript.sh

(cremefraiche)

Now that the file is owned by root and permissions correctly set, it cannot be opened by a user unless they sudo.

  • 1
    It is very unclear what you are asking. Are you trying to see when a user invokes sudo, as you just said, or are you trying to run a script as root, like your question says? "I have a shell script, that needs to be run with root privileges. How can I enforce that?" – cremefraiche Dec 11 '14 at 13:46
  • 1
    I think what's meant here is that if you also set the script as executable only by owner (that bit was left out), other users would more or less have to use sudo to run it. – goldilocks Dec 11 '14 at 14:49
  • 1
    I omitted changing file permission as the default umask behavior is to allow owner and group execute, both of which in this case are root and would force a use of sudo. Just a note, our conversation took place before question and answer edit. – cremefraiche Dec 11 '14 at 14:52
  • 1
    I have no idea, how I didn't think of that. Will do it this way. Thanks a lot for your time. – Minix Dec 11 '14 at 15:15
  • 1
    @muru Soz. 750 all the things and my answer works. Should I delete? Edit: omg, I need sleep. I would never give everyone read AND write. Let alone read. – cremefraiche Dec 11 '14 at 15:56

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.