13

I have ubuntu 8.04 and I want to write a bash script that runs as root which every user can run.

I myself can do sudo.

How do I do that?

CLARIFICATION: I don't want to do it with sudo, because then users will have to type their password. I just want them to run the script as root, perhaps something setuid, dunno.

5 Answers 5

31

If this was a normal binary, you could setuid by running

# chmod u+s /path/to/binary

Unfortunately, scripts can't be setuid. (Well you can, but it's ignored). The reason for this is that the first line of the script tells the OS what interpreter to run the script under. For example if you had a script with:

#!/bin/bash

You'd actually end up running

/bin/bash /path/to/script

Obviously, you'd need the interpreter to be setuid, which would then mean all scripts would be setuid. This would be bad.

You can do this with sudo by putting the following in your /etc/sudoers file by running visudo.

ALL ALL=NOPASSWD: /path/to/script

And now any user can run

$ sudo /path/to/script

This allows them to run the script without typing in their password.

There is an alternative that doesn't require sudo in the command, which requires creating a small setuided binary that execs your script, but every additional setuid binary adds another potential security problem.

5
  • 1
    I think this is the answer I was looking for. Can't I setuid a bash script, only a binary? (Of course, I would take measures to make it uneditable)
    – flybywire
    Oct 18, 2009 at 10:24
  • No, you cannot make a script setuid.
    – wfaulk
    Oct 18, 2009 at 15:48
  • wfaulk: You used to be able to, but most recent Linux distros do not allow it anymore. You can use a tool like shc to 'compile' the script, and then make it setuid. Oct 20, 2009 at 20:01
  • wfaulk: Of course, that would be going out of your way to do something that is intentionally disabled, so it is probably a bad idea :-) Oct 20, 2009 at 20:06
  • Replace the term ALL with a user name to allow just that one sudoer to be able to run without entering a password.
    – Dave
    Mar 25, 2013 at 15:52
4

I needed to insert that line AT THE END of /etc/sudoers : ALL ALL = NOPASSWD: <filename> Apparently, a later %admin ALL=(ALL) ALL override required a password for admin users.

There is no security problem allowing a script to be run as root as long as the script does a well determined, harmless, allowed action and, if values for any parameters cannot cause the script to misbehave.

But there is a gotcha...

Always use full paths in command and file names. If you write something like echo Hello world! in myrootscript, someone might write a ~/bin/echo script and myrootscript would execute as root whatever is in it.

/bin/echo "Hoping this will keep you safe" :-)

1
  • if it is possible for a non-root user on the machine to edit that script then it is possible for that user to take over the machine. If that same user has a weak password then nothing is keeping your machine from being totally compromised.
    – Dave
    Mar 25, 2013 at 15:50
2

By default, members of the wheel group are permitted to sudo any command as root. This is probably how you are using sudo to date.

To permit another user you will need to create a sudoers rule. For example:

mickey.mouse ALL = (root) NOPASSWD: /usr/local/bin/test.sh

Will allow the user mickey.mouse to run the command /usr/local/bin/test.sh as root without requiring an additional password prompt.

You should read this document for more information.

3
  • Debian/Ubuntu use the admin group rather than wheel. It's possibly a slightly more accurate name. Oct 18, 2009 at 9:58
  • Call me old fashioned, but.. ;)
    – Dan Carley
    Oct 18, 2009 at 9:59
  • 1
    old fashioned :P Oct 18, 2009 at 10:03
1

Use chmod +s <filename> to se the suid bit. This means that when the file is executed, it runs with the permissions of the owner of the file (so chown it to root to make it run as that).

However, this can be VERY dangerous with something like a bash scripts, because a user finds a way to change it, they can easily gain a root shell. Make sure that it can't be written to by anyone except root.

Linux doesn't allow you to setuid on scripts, to do this you'd have to compile it as a program. Instead, you can use the sudoers file (/etc/sudoers), and add a line like this.

<username> ALL = NOPASSWD: /path/to/script

1

Another alternative: you can do a small setuid C wrapper around that script that

  • checks for any limitations you might want to enforce (user list, time, system load,...)
  • logs/audits execution if desired
  • execs the script

Kind of like your own subset of the multiple capablities of sudo.

You must log in to answer this question.

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