Run a Bash script as root with Objective-C / Cocoa - objective-c

Given that there is a file called copystuff in the Resources folder in a an xCode project, and that file reads:
#!/bin/sh
cp -R /Users/someuser/Documents /Users/admin/Desktop
And if this bit of code below is linked to a button in IB ... it will copy the /Users/someuser/Documents directory to /Users/admin when the button is pressed in a Cocoa app... It works when app is launched in an admin account ( using OS X 10.5.x here) ...
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/sh"];
[task setArguments:[NSArray arrayWithObjects:[[NSBundle mainBundle]
pathForResource:#"copystuff" ofType:#"sh"], nil]];
[task launch];
My question is.. is there a way to have NSTask run a script running as root while this code is called from a non-admin account? Or asked another way..can Objective-C be coded to run scripts from say /usr/bin as root from a non-admin account?

I would strongly recommend against using an external script like this. It's much better to do this with NSFileManager and keep this inside of controlled code. But to the question of how to become root, you want to look at Authorization Services. This site will walk you through how to create an application that escalates its privileges, including the appropriate UI elements for it.

If I'm understanding what you want to do, you're trying to have a non-privileged user be able to perform a privileged action without needing to authenticate?
setuid shell scripts are considered a gigantic security risk, so they're disallowed by the kernel. If you want to write a separate executable program, however, you can set the set-user-ID-on-execution or set-group-ID-on-execution bits on it and get the behaviour you want. Be careful, you're now in the land of big potential security problems...
man chmod for more information.
Here's a quick and dirty example:
$ echo "Hello, world!" > file
$ sudo chown root file
$ sudo chmod 600 file
$ cat file
cat: file: Permission denied
But I can write a program:
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
setuid(0);
system("cat file");
return 0;
}
Which can do what we'd like:
$ cc -Wall -o app main.c
$ chown root app
$ chmod 4755 app
$ ./app
Hello, world!

Related

How to automate commands on Cygwin

Hi I am looking to automate my file transfering to my Jailbroken iPhone over USB with a bash file. Which will launch the relay then do the file transfers
With this here I installed and successfully transfered files to my iPhone with cygwin but now I want to automate the file transfer.
First I need to start the relay with cygwin and those commands are required
cd pyusbmux/python-client/
chmod +x *
./tclrelay.py -t 22:2222
so I created a .sh file that does it but when I launch it cygwin gives me those errors
This is what should happen on the left and the result of the script on the right
How can I make cygwin open with thoses commands
In addition to be sure that tcpON.sh has proper line termination with d2u of dos2unix package:
d2u tcpON.sh
You should add a proper SHEBANG on the first line of your script
https://linuxize.com/post/bash-shebang/
#!/bin/bash
cd /cygdrive/e/Grez/Desktop
cd pyusbmux/python-client/
chmod +x *
./tclrelay.py -t 22:2222
You can use as base the Cygwin.bat and make a tcpON.bat batch file like:
C:
chdir c:\cygwin64\bin
bash --login /cygdrive/e/Grez/Desktop/tcpON.sh
Verify the proper cd command to be sure that you are always in the expected directory.
It is not the only way but probably the most flexible (IMHO)

Bash script in Mac OS X app, calling custom app from system

In my bash script i have:
program=*program_name*
condition=$(which $program 2>/dev/null | grep -v "not found" | wc -l)
if [ $condition -eq 0 ] ; then
echo "$program is not installed";
echo -n *mypass* |sudo -S gem install $program;
fi
First of all, it installs program every time. It shows that program is not installed, but i can use it from terminal.
...then, i need to use this program in my cocoa application, for example
program --help
Using
system([pathToFile UTF8String]);
i get:
path_to_bundle/myBashScript.sh: Permission denied // Where path is in bundle
path_to_folder/myBashScript.sh:line 30: program: command not found // Where path is from other system folder
Using NSTask i get program: command not found every time.
I don't understand why this is happening. And i would like to know how i can use this program in my cocoa app.
So, i have found the solution.
When you're trying to run the custom system program from the cocoa app, you should give the full path to the binary.
The problem is in:
program=*program_name*
*program_name* should be full path to binary, in my case it was /Library/Ruby/Gems/2.0.0/gems/program-version/bin/program
For additional information about installation paths:
https://wiki.haskell.org/Mac_OS_X_Common_Installation_Paths
http://help.rubygems.org/discussions/problems/739-how-to-run-applications-installed-by-gem

Objective-C Environment Setup For Ubuntu-Linux

I don't have the Mac machine for ios development. Now I am in a learning stage and want to start the ios development on Linux. So is it possible to run the Objective-C Code on Linux environment?
Yes it is possible in Ubuntu to Run the Objective-C code in the following way:
In Ubuntu, Install GNU Objective-C Compiler and the Gnu-step Development Libraries with the following command::
sudo apt-get –y install gobjc gnustep gnustep-devel
Now type the Program given below and save the file with .m extension.
For Example say, hello.m
// 'Hello World' Program in Objective-C
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog (#"Hello, World!");
[pool drain];
return 0;
}
Now Compile the Program with the following command:
gcc $(gnustep-config --objc-flags) -o hello hello.m $(gnustep-config --base-libs)
Or you could write this sample Makefile:
CC := gcc
GNUSTEP_LIBS = $(shell gnustep-config --base-libs)
GNUSTEP_FLAGS = $(shell gnustep-config --objc-flags)
.PHONY = clean all
PROGS = hello class_hello
all: $(PROGS)
%.o: %.m
$(CC) $(GNUSTEP_FLAGS) -c $^
hello: hello.o
$(CC) -o $# $^ $(GNUSTEP_LIBS)
clean:
rm $(PROGS) *.o
And run:
make
Now Run the executable with the following command:
./hello
OUTPUT -> 2014-11-14 15:47:32.628 hello[2786] Hello, World!
The Format of the Output is something like this-
<DATE> <TIME> <NAME OF THE EXECUTABLE[NUMBER]> <ACTUAL OUTPUT>
Unfortunately, in order to develop for iOS you will need OS X on your machine. An alternative involves creating a virtual machine on your computer and installing OS X and XCode on it. I've heard this solution works perfectly fine for people provided their computer can handle it.
More information on creating a "hackintosh" may be found here.
Sure. LLVM/Clang is available as a package for most Linux distributions and is a great environment for learning Objective-C.
However, you're going to hit a wall very quickly. Namely, the iOS (or OS X) development stack -- the frameworks, APIs, and tools -- aren't available for Linux and, thus, you're out of luck the moment you want to do anything graphical.
There are projects -- GNUStep, Cocotron -- that are an implementation of a Cocoa-like set of APIs (derived directly from OpenStep) and those are great to learn, but you still won't be writing real iOS / OS X apps.

Command works in shell but not Objective-C or C

I want to run the following shell command in Objective-C
sshfs -C -p 22 user#remote.computer.com ~/local/directory/path
using the command system("sshfs -C -p 22 user#remote.computer.com ~/local/directory/path");
but I get sh: sshfs: command not found in NSLog.
If I copy and paste it into terminal however, it works.
The path used by an GUI application does not include any changes you have made in your shell files in your home directory (e.g. ~/.bashrc)
One way is to use the full path in the system call. (i.e. /Users/username/Projects - ~ are not automatically expanded) In a Cocoa app I would use NSTask to give more control

Executing sh file with sudo in OS X gives an error

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.