Executing sh file with sudo in OS X gives an error - objective-c

I've developed an application where I need to run some script under root. Also sh script contains "sudo" commands. For running sh script under root I use STPrivilegedTask class from github:
https://github.com/sveinbjornt/STPrivilegedTask
Here how I run a script:
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:#"my_script" ofType:#"sh"];
STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:scriptPath];
int result = [task launch]; // return error 60031 which means:
//errAuthorizationToolExecuteFailure = -60031, /* The specified program could not be executed. */
And here is a script I use:
#!/bin/bash
sudo mkdir -p /usr/local/myfolder
sudo su - root -c "launchctl load -F /System/Library/LaunchDaemons/com.mydaemon.daemon.plist"
I use OS X Mavericks 10.9.4
EDIT:
After I set "chmod +x my_script.sh" for script it runs script. But now I receive next errors in console:
sudo: no tty present and no askpass program specified
sudo: no tty present and no askpass program specified
Seems that my admin credentials I put didn't applied with script I run. Any ideas how to fix that?

Here are two solutions taken in part from this stackexchange thread, which I can't test because I do not currently own a mac.
Solution 1: Use OSAScript to run the command in the first place
#!/bin/bash
sudo mkdir -p /usr/local/myfolder
osascript -e "do shell script \"mkdir -p /usr/local/myfolder\" with administrator privileges"
osascript -e "do shell script \"launchctl load -F /System/Library/LaunchDaemons/com.mydaemon.daemon.plist\" with administrator privileges"
Solution 2: Use OSAScript to prompt for a password and use that with sudo
#!/bin/bash
pw = "$(osascript -e 'Tell application "System Events" to display dialog "Password:" default answer "" with hidden answer' -e 'text returned of result' 2>/dev/null)"
echo $pw | sudo -S mkdir -p /usr/local/myfolder
echo $pw | sudo -S su - root -c "launchctl load -F /System/Library/LaunchDaemons/com.mydaemon.daemon.plist"

If you're using STPrivilegedTask properly, then the script should already be running with root privileges so the sudo commands are actually not needed in that case.
You should use something akin to:
sudo=
[[ $(id -u) != 0 ]] && sudo=sudo
$sudo <command that would need sudo>
which should prevent the errors about not having a tty, which are related to invoking the sudo command in a GUI application.

Related

Why do I have to spawn a new shell when doing remote sudo ssh commands to get proper file permissions?

I'm using password-less key based login with sudo to execute remote commands. I have figured out that I have to spawn a new shell to execute commands that write to root areas of the remote file system. But, I would like a clear explanation of exactly why this is the case?
This fails:
sudo -u joe ssh example.com "sudo echo test > /root/echo_test"
with:
bash: /root/echo_test: Permission denied
This works fine:
sudo -u joe ssh example.com "sudo bash -c 'echo test > /root/echo_test'"
It's the same reason that a local sudo echo test >/root/echo_test will fail (if you are not root) -- the redirection is done by the shell (not the sudo or echo command) which is running as the normal user. sudo only runs the echo command as root.
With sudo -u joe ssh example.com "sudo echo test > /root/echo_test", the remote shell is running as a normal user (probably joe) and does not have permission to write to the file. Using an extra bash invokation works, because sudo then runs bash as root (rather than echo), and that bash can open the file and do the redirect.

AIX script hangs when using /dev/null > 2>&1

I am trying to run a script in AIX to execute another script on a remote server. In addition to the remote script i need to send the stdout to /dev/null. The same command works fine on another server but when I run on the current server it hangs, any advice?
su - test -c "rsh testserver /scripts/testme" 2>&1 >/dev/null1
In your comment you write that a menu is presented when the user logins.
Let's say this is done in the .profile file, using echoes and a read command.
When a menu is presented, the read command in the menu code will not be skipped by redirecting the output. The menu still waits for your input and the su command seems to hang.
Can you change your .profile or .bashrc so that it will skip presenting the menu when called using a su command? When this is called during startup, you can look at the returncode of tty. When you use the su command from the commandline, you should look for another solution.
When your root shell is ksh, you can try the following:
if [[ "$(ps -fp $$)" != *"-ksh -c "* ]]; then
echo "Now I should call the Menu"
fi

Running ssh command and keeping connection

Is there a way to execute a command before accessing a remote terminal
When I enter this command:
bash
$> ssh user#server.com 'ls'
The ls command is executed on the remote computer but ssh quits and I cannot continue in my remote session.
Is there a way of keeping the connection? The reason that I am asking this is that I want to create a setup for ssh session without having to modify the remote .bashrc file.
I would force the allocation of a pseudo tty and then run bash after the ls command:
syzdek#host1$ ssh -t host2.example.com 'ls -l /dev/null; bash'
-rwxrwxrwx 1 root other 27 Apr 1 2005 /dev/null
bash-4.1$
You can try using process subsitution on the init file of bash. In the example below, I define a function myfunc:
myfunc () {
echo "Running myfunc"
}
which I transform to a properly-escaped one-liner echoed in the <(...) construct for process subsitution for the --init-file argument of bash:
$ ssh -t localhost 'bash --init-file <( echo "myfunc() { echo \"Running myfunc\" ; }" ) '
Password:
bash-3.2$ myfunc
Running myfunc
bash-3.2$ exit
Note that once connected, my .bashrc is not sourced but myfunc is defined and properly usable in an interactive session.
It might prove a little difficult for more complex bash functions, but it works.

Login via Shell Script

My issue is that I want run a script from root for which I always have to login with root manually by typing "su -" on command line.
My query is that the script which I am executing it automatically login with root by just prompting me for password. Help me!!!
::::::::::Script:::::::::::::
if [ "$(whoami)" != "root" ]; then
echo -e '\E[41m'"\033[1mYou must be root to run this script\033[0m"
**su - # at this line I want to login as root but it is not working**
exit 1
fi
sleep 1
if [ "$(pwd)" != "/root" ]; then
echo -e '\E[41m'"\033[1mCopy this script to /root & then try again\033[0m"
cd /root
exit 1
fi
sleep 1
echo -e '\E[36;45m'"\033[1mDownloading Flash Player from ftp.etilizepak.com\033[0m"
sleep 2
wget -vcxr ftp://soft:S0ft\!#ftp.abc.com/ubuntu/ubuntu\ 12.04/adobe-flashplugin=/install_flash_player_11_linux.i386.tar.gz
cd ftp.abc.com/ubuntu/ubuntu\ 12.04/adobe-flashplugin/
sleep 1
echo -e '\E[42m'"\033[1mUnzipping .tar File...\033[0m"
sleep 1
tar -xzf install_flash_player_11_linux.i386.tar.gz
echo "Unzipping Compeleted"
sleep 2
echo -e '\E[42m'"\033[1mCopying libflashplayer.so\033[0m"
cp libflashplayer.so /usr/lib/mozilla/plugins/
:::::::::::::::END:::::::::::::::::::::
I'm not sure if I understand your question but I suppose you want to run something inside you script with root privileges - then you shuold use "sudo" command.
You can also suppress the password prompt, this can be configured in sudoers" configuration file.
Some more info here:
https://unix.stackexchange.com/questions/35338/su-vs-sudo-s-vs-sudo-bash
Shell script calls sudo; how do I suppress the password prompt
There is tons of examples, google something like "linux sudo examples" and you will get lots of examples how to use su, sudo ans sudoers commands.
According to your comments to my previous answer, here is how i do it:
There are two files in the same directory:
-rwx------ 1 root root 19 Sep 10 13:04 test2.sh
-rwxrwxrwx 1 root root 29 Sep 10 13:06 test.sh
File test.sh:
#!/bin/bash
# put your message here
su -c ./test2.sh
File test2.sh:
#!/bin/bash
echo You run as:
whoami
# put your code here
Result:
> ./test.sh
Password:****
You run as:
root
If you want to suppress the password prompt for this script only, replace "su -c" with "sudo" and configure sudoers file according to insctructions from here: https://askubuntu.com/questions/155791/how-do-i-sudo-a-command-in-a-script-without-being-asked-for-a-password

Remember sudo password in shellscript

I want to make a shellscript to install Wine on a Mac
and i want the user to enter his/her password so the script can use it later on to make the installation unattended by automatically entering the password on "sudo" commands. This is what i got for now:
clear
echo Wine Installer v1.0
echo -------------------
echo by Sydcul
sleep 4
clear
echo "Please enter your OS X user password."
echo "It is needed in some parts of the installation."
read PASSWORD
echo "Wine installation starting."
echo "Please do not shut down your system."
mkdir winetmp
cd winetmp
curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.3.tar.bz2
tar xjvf MacPorts-2.0.3.tar.bz2
cd MacPorts-2.0.3
echo $PASSWORD | ./configure && make && sudo make install
echo $PASSWORD | sudo port -v selfupdate
echo $PASSWORD | sudo port -v install xorg
echo $PASSWORD | sudo port -v install wine
rm -rf ~/winetmp
clear
echo "Wine is successfully installed and ready for use!"
But at a certain point is still asks for the password.
How can i fix this?
Honestly, I would drop all that $PASSWORD stuff and remove the sudo from all your commands. You are writing an installation script, which should be run with elevated privileges. Have your users execute your script with sudo ./installwine.sh, and then run the commands in the script without sudo. All your port -v stuff will inherit the elevated privileges.
If you'd like to offer your user a nice error message if they forget to run the script with sudo (rather than just having your first call to port fail cryptically), you could check to see if the effective user ID ($EUID) is 0, and print the error message and exit otherwise. See https://askubuntu.com/questions/30148/how-can-i-determine-whether-a-shellscript-runs-as-root-or-not.
You can prompt the user for the password for the first time and then save it in a file (and don't forget to encrypt it).
The next time when you need it you can easily read it from the same file and store it in a variable and then use this command
echo $variablename | sudo -S command
Actually I think sudo doesn't accept password from stdin (you need to specify -S parameter to enable this).
As workaround you can execute sudo su to gain root privileges for all commands.
UPD: I'm not recommend to save password to file cause it is very bad solution from security point.
UPD2: You forget about Xcode, if it is not installed this script fails on compile stage :)
Why don't you just use the custom prompt option for sudo, and let it ask for the password if it needs it?
You start by checking if they're already root or not like this:
SUDO=""
if [[ 0 == $(id -u) ]]
then
SUDO="sudo "
fi
$SUDO command 1
$SUDO command arg arg arg
and then optionally combine that with the ability to customize the sudo prompt using the -p option.
then
SUDO="sudo -p \"I need elevated access for this part. Please enter %u's password:\" "
fi
You still get control over the interface, but don't prompt for a password unless you need it. Some people may have sudo set up for nopassword operation, for example. Others might run your installer as root. Or maybe their pasword is already cached with sudo. Etc. It's best to let sudo manage prompting, possibly using an askpass program (see the -A option) if necessary.