run bash script as root from php page - bash

I have a php page.
It calls a validation bash script that checks variables passed from the php page.
I then call another bash script that I need to execute under root user. I have followed the guide here How to run from PHP a bash script under root user and still can not get script to execute as root.
I have the following:
php page
$bashFile = shell_exec('./Validation.sh "'.$coinName.'" "'.$coinNameAbreviation.'" "'.$blockReward.'" "'.$blockSpacing.'" "'.$targetTimespan.'" "'.$totalCoins.'" "'.$firstBitAddy.'" "'.$seedNode.'" "'.$seedName.'" "'.$headline.'" ');
echo "<pre>$bashFile</pre>";
the validation file:
sudo nohup /bin/bash /usr/sbin/CoinCreationBashFile "$coinName" "$coinNameAbreviation" "$blockReward" "$blockSpacing" "$targetTimespan" "$totalCoins" "$firstAddyBit" "$seedNode" "$nameSeedNode" "$headline" "$blocksPerDay" "$startingDifficulty" >> /tmp/BASH2log.txt 2>&1 &
I have added
www-data ALL=NOPASSWD /usr/sbin/CoinCreationBashFile
to the end of the sudo visudo
and did:
chown root:root /usr/sbin/CoinCreationBashFile
chmod 755 /usr/sbin/CoinCreationBashFile
was running it from usr/sbin from suggestion here http://ubuntuforums.org/showthread.php?t=1848069
Can anyone see what I am doing wrong?? Many thanks
edit: I can run the CoinCreationBashFile script without the sudo command and it runs ok up to one point where it needs root priv... so i know the script working, and executing from the terminal the script runs perfectly as desired. output in tmp/BASH2log.txt
sudo: no tty present and noaskpass program specified

This question is similar to sudo in php exec() and they did not arrive at a conclusion.
In your case, since only one bash script needs to be executed in this fashion, considering using setuid instead:
$ su
[enter password]
chown root:root something.sh
chmod 4755 something.sh
exit
Note: Some Linux distributions disable setuid for shell scripts by default for security reasons.
Update: Apparently no commonly used Linux distribution today allows setuid on shell scripts. Perl used to be the exception, but suid-perl is now deprecated.
The only way to execute your bash script using this method is to invoke it from a compiled binary. See the example with the C code on how to do this.

I recently published a project that allows PHP to obtain and interact with a real Bash shell, you can easily get a shell with root. Get it here: https://github.com/merlinthemagic/MTS
After downloading you would simply use the following code:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$strCmd = "/usr/sbin/CoinCreationBashFile ".$coinName." ".$coinNameAbreviation." ".$blockReward." ".$blockSpacing." ".$targetTimespan." ".$totalCoins." ".$firstAddyBit." ".$seedNode." ".$nameSeedNode." ".$headline." ".$blocksPerDay." ".$startingDifficulty." >> /tmp/BASH2log.txt 2>&1 &";
$return1 = $shell->exeCmd($strCmd);
//if there is any return from the script you can wait for the return
//or you can trigger like you have it now and get no return.

You have a typo in visudo entry. There is no R in the NOPASSWD. It should be:
www-data ALL=NOPASSWD /usr/sbin/CoinCreationBashFile

Related

Running Docker commands included in a shell script alongside other Linux commands and switching users

Using the Linux terminal, I run bash scripts (.sh files) containing sequences of commands I want to execute.
The issue is that I am unable to run a Docker command from within my shell script. I can run this Docker command when it's typed directly at the terminal with root privileges but not when I include it in the shell script file.
My script executed as a general user from command line, looks like this:
#!/usr/bin/env bash
cd /home/user/docker_backup
# remove /home/user/docker_backup/data
rm -rf data
# Switch to root privileges. my system is set to only run Docker as root
su
# Copy a folder from Docker container to host OS
docker cp <container-name>:/home/user/data /home/user/docker_backup
# More general user commands
cd ..
My code only runs until the su line above. After i enter the root password, nothing happens. if i type exit, i get permission errors, meaning the docker cp command failed.
**
This is my desired solution
**After thorough research, as I wanted to run my script as a general user, and only run certain commands as Root when necessary, I came up with a solution that works.
My script now looks like this (run with
$ sh script_name.sh):
#!/usr/bin/env bash
cd /home/user/docker_backup
# remove /home/user/docker_backup/data
rm -rf data
# Switch to root privileges. my system is set to only run Docker as root
su - root -c "docker cp <container-name>:/home/user/data /home/user/docker_backup"
# More general user commands
cd ..
Run shell script as general user. For commands that require root privileges, I use su - root -c "<command>". Terminal prompts for root password and executes command in quotes as root, then shell proceeds as general user.
Actually posting this as an answer:
You switch your current user to root during the script, but the script was executed by your own user.
So the docker cp command will also be executed as your own user, but you will be logged into the root account.
This results in you not seeing the output of docker cp (which might give you insight to not working - I think insufficient privilege).
A solution to this is either using sudo before docker cp, starting the script as root or adding your user to the group "docker", which authorizes your user to use the docker commands
I had the similar issue where the docker commands were running fine on the Terminal but the same commands were not running when I compiled them into a bash script and the issue was basically because of two reasons.
The docker commands need to be run with uplifted privileges that is with the sudo command ( Eg: sudo docker ps works but docker ps won't work). One could add the current user to docker group so that we need not use sudo with each docker command. Please visit this link and follow the section 2 to do the same.
Run the script in the correct way
One should have #! bin/bash at the starting of the script. It is a shebang that is required by each script.
One should save the file without .sh extension
One should provide the execution permission to the script by giving command chmod 777 script_name
run the script with bash script_name

run inline shell script as root

I have a user, who's a passwordless sudoer. I need to execute shell script file with him, and make him execute one block as sudo. E.g:
su root <<"AS_ROOT"
# do something with my linux
AS_ROOT
But nothing works. I tried:
su - root <<...
sudo -s -- <<...
It barks back at me. I'm on ubuntu 16.04 lts.
Thank you.
As Cyrus points out, su is a different utility to which sudo's configuration doesn't apply.
It sounds like you're looking for something like this:
sudo -s <<'AS_ROOT'
echo "Hi from $USER."
AS_ROOT
This should output Hi from root.
Note that -s is needed to tell sudo to create a shell in order to interpret the commands passed via stdin (the here-doc). That shell is the current user's default shell, as reflected in environment variable $SHELL.

Run a command as the standard user, from a sudo elevated script

If a bash script has been executed with sudo, how can a command within the script run as the currently logged in user, instead of root and then revert to root to continue running other commands?
For example: -
#!/usr/bash
touch fileOwnedByRoot.txt
touch fileOwnedByUser.txt
touch otherRootFile.txt
If this script is run with sudo, without changing the order of commands, how can the 2nd touch command be run as the standard user?
The script is only a simple example, so using chmod to change ownership of files created is irrelevant.
The actual script I'm using is being run by an installer, so running with elevated privileges is a requirement, but specific commands must be run as the user running the installer, whose name is not known.
Use su - another_user -c "<command>" to run that specific command:
#!/bin/bash
touch /tmp/f1
su - another_user -c "touch /tmp/f2"
touch /tmp/f3
As commented by chepner below, you need to use $SUDO_USER or $SUDO_UID to get the name of the real user running the sudo command:
su - $SUDO_USER -c "touch /tmp/f2"
This way, the file will be touched by the user running the command.
You can test with:
#!/bin/bash
echo "sudo_user: $SUDO_USER"
echo "sudo_uid: $SUDO_UID"
And run the script either with ./script or sudo ./script. In the second case the values will be populated.
Don't run the script as sudo, just the commands that require elevated privileges.
#!/bin/bash
sudo touch fileOwnedByRoot.txt
touch fileOwnedByUser.txt
sudo touch otherRootFile.txt
According to the man page the environment variable SUDO_USER is set when you run sudo, so you could do something like:
#!/usr/bash
touch fileOwnedByRoot.txt
sudo ${SUDO_USER} touch fileOwnedByUser.txt
touch otherRootFile.txt
I haven't tested this, and don't know if it work differently on OSX, but it's worth a shot.

How do I run a shell script with administrator privileges through AppleScript without prompting for a password?

I want to have my AppleScript application run a Python script with sudo, but I don't want the application to prompt the user for a password (our users do not have sudo privileges).
The Python script has been added to the /etc/sudoers file appropriately (ALL ALL=NOPASSWD: /path/to/script.py). In the terminal, I can do (as a regular, non-privileged user):
$ sudo ./script.py
and it runs perfectly well. But in AppleScript when you try to do:
do shell script "sudo ./script.py"
You of course get the "sudo: no tty present and no askpass program specified" error. But if you change it to:
do shell script "./script.py" with administrator privileges
AppleScript insists on presenting a popup window to ask for the password. I have also tried passing a null password to sudo with a pipe:
do shell script "echo '' | sudo -S ./script.py"
but that also does not work. (I think it tries to run sudo individually first and then pass the command through, which won't work because the user doesn't have sudo privileges!)
I need a solution where AppleScript will run the Python script with sudo. I would prefer the script stays unreadable and un-executable by average users for security reasons, and is only executed through the AppleScript. (I know that, hypothetically, the users could call sudo script.py and it would run, but that's assuming they even know about sudoers; I'm trying to keep it as secure as possible while still usable).
I'm still pretty new to AppleScript, so any help would be greatly appreciated! Thanks!
When I added ALL ALL=NOPASSWD: /Users/myusername/a to sudoers and ran echo $'#!/bin/bash\nsay $(ls ~root|head -n1)'>~/a;chmod +x ~/a, do shell script "sudo ~/a" ran the script as root without requiring a password.
I'm guessing the problem is that you specified the path like do shell script "sudo ./script.py". Try to use do shell script "sudo ~/script.py" instead. The default working directory is for do shell script is / and not ~/.

Changing to root user inside shell script

I have a shell script which needs non-root user account to run certain commands and then change the user to root to run the rest of the script. I am using SUSE11.
I have used expect to automate the password prompt. But when I use
spawn su -
and the command gets executed, the prompt comes back with root and the rest of the script does not execute.
Eg.
< non-root commands>
spawn su -
<root commands>
But after su - the prompt returns back with user as root.
How to execute the remaining of the script.
The sudo -S option does not help as it does not run sudo -S ifconfig command which I need to find the IP address of the machine.
I have already gone through these links but could not find a solution:
Change script directory to user's homedir in a shell script
Changing unix user in a shell script
sudo will work here but you need to change your script a little bit:
$ cat 1.sh
id
sudo -s <<EOF
echo Now i am root
id
echo "yes!"
EOF
$ bash 1.sh
uid=1000(igor) gid=1000(igor) groups=1000(igor),29(audio),44(video),124(fuse)
Now i am root
uid=0(root) gid=0(root) groups=0(root)
yes!
You need to run your command in <<EOF block and give the block to sudo.
If you want, you can use su, of course. But you need to run it using expect/pexpect that will enter password for you.
But even in case you could manage to enter the password automatically (or switch it off) this construction would not work:
user-command
su
root-command
In this case root-command will be executed with user, not with root privileges, because it will be executed after su will be finished (su opens a new shell, not changes uid of the current shell). You can use the same trick here of course:
su -c 'sh -s' <<EOF
# list of root commands
EOF
But now you have the same as with sudo.
There is an easy way to do it without a second script. Just put this at the start of your file:
if [ "$(whoami)" != "root" ]
then
sudo su -s "$0"
exit
fi
Then it will automatically run itself as root. Of course, this assumes that you can sudo su without having to provide a password - but that's out of scope of this answer; see one of the other questions about using sudo in shell scripts for how to do that.
Short version: create a block to enclose all commands to be run as root.
For example, I created a script to run a command from a root subdirectory, the segment goes like this:
sudo su - <<EOF
cd rootSubFolder/subfolder
./commandtoRun
EOF
Also, note that if you are changing to "root" user inside a shell script like below one, few Linux utilities like awk for data extraction or defining even a simple shell variable etc will behave weirdly.
To resolve this simply quote the whole document by using <<'EOF' in place of EOF.
sudo -i <<'EOF'
ls
echo "I am root now"
EOF
The easiest way to do that would be to create a least two scripts.
The first one should call the second one with root privileges. So every command you execute in the second script would be executed as root.
For example:
runasroot.sh
sudo su-c'./scriptname.sh'
scriptname.sh
apt-get install mysql-server-5.5
or whatever you need.

Resources