How to make a script run commands as root
I’m new to Ubuntu and bash scripts, but I just made runUpdates.sh and added this to my .profile to run it:
if [ -f "$HOME/bin/runUpdates.sh" ]; then . "$HOME/bin/runUpdates.sh" fi
The problem I’m having is, I want the script to run as if root is running it (because I don’t want to type my sudo password) I found a few places that I should be able to do sudo chown root.root
#!/bin/sh echo "user is $" #check for updates update=`cat /var/lib/update-notifier/updates-available | head -c 2 | tail -c 1`; if [ "$update" = "0" ]; then echo -e "No updates found.\n"; else read -p "Do you wish to install updates? [yN] " yn if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then echo -e 'No\n'; else echo "Please wait. "; echo `sudo apt-get update`; echo `sudo apt-get upgrade`; echo `sudo apt-get dist-upgrade`; echo -e "Done!\n"; fi fi #check for restart restartFile=`/usr/lib/update-notifier/update-motd-reboot-required`; if [ ! -z "$restartFile" ]; then echo "$restartFile"; read -p "Do you wish to REBOOT? [yN] " yn if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then echo -e 'No\n'; else echo `sudo shutdown -r now`; fi fi
I added the user is to debug, it always outputs my user not root, and prompts for the sudo password (since I’m calling the commands with sudo) or tells me are you root? (if I remove sudo) Also, is there a way to output the update commands stdout in real time, not just one block when they finish? (I also tried with the shebang as #!/bin/bash )
How do I run a shell script as root (sudo)?
I have a SVN repository server that runs under the repository user. I want to run a script after every post-commit action. I wrote a shell script that runs from the hook after every commit. It needs to be run as root. This is why I used sudo in the script, but it didn’t work. Is there any way to run the script as root?
sudo su echo "password" svn export --force file:///home/repository/trunk/ /home/memarexweb/public_html/devel/ chmod -R 777 /home/memarexweb/public_html/devel/
one option could be to disable password but isnt really a good solution maestric.com/doc/unix/ubuntu_sudo_without_password
5 Answers 5
I was searching around and found this useful solution:
Edit your sudoers file to allow running certain commands without a password.
It’s best to split your post-commit script into two parts, one of which will be run through sudo .
loqman ALL=(root) NOPASSWD: /usr/local/bin/svn-postcommit-export
#!/bin/sh sudo /usr/local/bin/svn-postcommit-export
#!/bin/sh svn export --force file:///home/repository/trunk/ /home/memarexweb/public_html/devel/ chmod -R 777 /home/memarexweb/public_html/devel/
starts a new process, owned by the root user. After that process is terminated or stopped, the next line is executed, again as the user that executes the script.
A possible solution is to run the whole script using sudo, and to give that use sudo rights to exectute the scripts. In order to do that, you need to edit the /etc/sudoers file using the visudo command.
In the last line of your script, you’re changing the mode of /home/memarexweb/public_html/devel/ to 777, so user «repository» should be able to copy files to that directory without root privileges. In that case, you don’t need to use sudo or su.
However, changing the permissions of the directory to 777 is dangerous, as it allows anyone to write to that directory and create or delete files. It would be better to change the ownership of the directory to user «repository» and change the mode to 755. If that’s not feasible, you may be able to add a POSIX ACL allowing «repository» to write to the directory. You can Google «POSIX ACL» for more information, or read the man pages for getfacl and setfacl .
This will not work, the best thing is to put only the requires commands in the shell script. And then setuid the script itself, like this (using root):
Like this, executing this script will give you the permissions of the owner of the script (root).
EDIT: As mentioned in comments, stuid is not allowed for shell script. This solution works for executable files only.
Run script as root at login (no sudoer user, shell session)
Much like /etc/profile and ~/.profile but ran by root instead of the user is doing login. /etc/rc.local runs after boot but I need running the script before login. The user is not a sudoer one. Thanks!
There may be a way to do this, but it wouldn’t be like /etc/profile or ~/.profile because running code in those scripts is done by the user’s shell and is subject to control of the user, whereas if you don’t want the user to have the power to run programs as root themselves, then this will have to be done by some running service external to the user’s processes. . It might help if you could tell us the purpose of the script you want to run.
I need to perform one specific (—bind) mount for one specific user. I have tried fstab with owner and user options, but it does not work. /etc/rc.local is one option but it always performs the mount whether the user logs in or not. I have currently granted sudoer privileges for ‘mount’ to the user, but this is a workaround and don’t like granting any privileges to standard users. I think I will use rc.local instead. Thanks!
You could create a root script with only that particular mount command, and give to the user the privilege to run only that script (configuring /etc/sudoers ). A command with given options can be set directly in sudoers .
I have already tried that way. The thing is that when the time comes for running ‘mount’ inside the script, again ‘sudo’ is mandatory, because the script is ran by ‘user’ and not by ‘root’, so at the end of the day ‘mount’ must be granted too for ‘user’ and instead of just one only sudoers rule now I have two. This is my experience, so please, bear in mind tha I’m not an expert and maybe I have done something wrong. Thanks!
3 Answers 3
Just to go back to the sudoers method, I think you were almost there before you gave up. Looking at your latest comments, I’d just like to address something that will probably fix things for you:
If you run a script as root, you don’t need to call sudo from within it.
I have a script like this:
If I run sudo ./myscript I see root returned for both those. The session that script is running in is a root shell.
In short that means that everything you do in your script already has root permissions. You don’t need to call sudo (not that it should hurt — root usually has sudo permissions).
So write your script, chown it to root and chmod it to 700 (so only root can run, read, or edit it) and then just allow your user[s] to run it through sudoers. That should work.
If it’s not working, it’s likely a bigger issue with the script, not the permissions framework. I’d suggest giving a user full sudo access (adding to admin group is the easiest way) and then running your script.
Step 1. create a script with the bind command using any editor. For example:
sudo emacs bind_user_directories.sh
#!/bin/bash #NOTE: this file would be placed in /usr/local/sbin/ folder as bind_user_directories.sh #alternatively it could be placed in /etc/init.d/ . (I guess) ### BEGIN INIT INFO # Provides: bind_user_directories # Required-Start: # Required-Stop: # Should-Start: $named # Default-Start: 0 2 3 4 5 6 (I guess. ) # Default-Stop: 1 # Short-Description: mount --bind for a user # Description: runs mount --bind command for certain pre-defined directories for a specific user ### END INIT INFO # What is this? DESC="bind_user_directories" # See how we were called. case "$1" in start) log_progress_msg "bind directories for user. " sudo mount --bind /source/path /target/path log_progress_msg "done: bind directories for user" ;; stop) log_progress_msg "umount --bind directories for user. " sudo umount /target/path log_progress_msg "done: unbind directories for user" ;; restart) $0 stop sleep 1 $0 start ;; *) #log_success_msg "Usage: bind_user_directories " log_success_msg "Usage: service bind_user_directories " exit 1 ;; esac exit 0
Step 2. save bind_user_directories.sh and make it executable:
chmod a+x bind_user_directories.sh
Step 3. link it to a suitable location such as /usr/local/sbin:
sudo ln -s bind_user_directories.sh /usr/local/sbin/bind_user_directories.sh
Step 4. create the upstart script:
sudo emacs /etc/init/bind_user_directories.conf
description "runs mount --bind command for certain pre-defined directories for a specific user" start on filesystem and net-device-up IFACE!=lo stop on runlevel [!023456] console output respawn respawn limit 10 5 exec /usr/local/sbin/bind_user_directories.sh start
If this works for you, please let me know. You can check system log for messages after logging in. (I didn’t test it yet and I have never implemented anything like this before.) If you improve to the solution, please share your final solution here. Thanks.
How to run a script with root authority in Linux
I have to develop a Web site written in CGI. I would like to know how to run a script with root authority from CGI. Let’s say the script name is hello , I run it from CGI like system(«pathToTheFile/hello»). Now I would like to run this hello file as root; can anybody help me with this?
Normally the web-server you run to access your CGI script should be run on a system user ad not under root (e.g. a user calles apache who execute the apache httpd); after you just give that user the read and execute access to the script.
3 Answers 3
Generally the safest way to do this kind of thing is to use the setuid feature of UNIX-like OSs. If you set the owner of the hello program to be root , and then set the setuid bit:
Then no matter who executes the program, it will execute as root. This works for native executables, but not for interpreted scripts. If «hello» has to be a script, then this won’t work for you.
Now, I have to say that in general, setuid root programs aren’t a great idea. Often you can create a special user to own the script, and give that user some limited privileges needed, and then make the script setuid to that user.
No, that does not work for scripts. Only binaries. Also, you can’t set that, that would be a big security hole. The existing root account would have to set that. That might be you, however.
@Keith, you could have a script which runs a specially modified setuid shell (a «real» executable) passing another script as the parameter. This would get around that problem. Convoluted, yes, but there are ways around most problems.
@pax, true but you still have to setuid some binary somewhere. And this post didn’t mention that extra step, so I thought I would. Also, I disagree that it’s the safest way, since «no matter who executes» it it gets the elevated privileges. sudo is safer since you can define more fine-grained control over who can execute it (e.g. the UID of the web server only).
@Keith appears to be right: Linux doesn’t allow setuid scripts at all. I had this belief that it was at least configurable, but that doesn’t seem to to be the case; perhaps it once was. *BSD Unices, including OS X, allow them, and that’s where I spend more of my time these days. I edited my answer to reflect this.
Yes some older *nix do allow it, but Linux doesn’t. A good discussion about the history of it is here.
A much safer method of doing things as root from a web page is to disconnect the program execution from the web page. Instead, use Unix local sockets, named pipes, or a directory of queued jobs.
The directory is probably the easiest to handle. Set up a directory that your web page can write files into. When your page needs something done, write a file describing the job. Then you have a program running as root waiting for new jobs. It can run continuously if it needs fast response or it can run every minute or every few minutes using a crontab entry.
The normal method would be to have the executable file owned by the user you want to run it as, then set the SUID bit.
The method of using sudo usually requires user input for the password (there are ways around this but they’re hideously complex).
I suppose I don’t need to mention that setting the SUID bit is a very dangerous thing to do, yes? If there’s any other way to do what you want, you should use it.
One thing you may want to consider is to pose the question not in terms of the solution you need but in terms of the problem you want solved. Running as root is a solution and not necessarily a good one. Post what you’re trying to achieve rather than how, and we can help you out in a far less dangerous way.