0

Consider a third-party SDK with a command line application that needs to run as root on OSX. You build a Cocoa application in Objective C and have it installed in /Applications under the "root:wheel" (user: root, group: wheel) ownership. I already have that folder/file ownership working because my Installer application uses AppleScript to prompt for root and then does a chown and chmod for this.

So, what is the preferred programmatic way then for the Cocoa application to update the root's crontab so that the third-party command line application runs under the root context? I mean, when I run the Cocoa application, does it run under root because that's how I set the file ownership in the installer? Or, does Apple launch it as the user who logged in? If the application runs under the root context, then I guess ordinary file I/O would work. If, even if I have installed the Cocoa application with root ownership, it runs as the user who logged in to the laptop, then somehow I need to escalate privileges to do that file I/O as root. And I'd like to do so without having to prompt for keychain access each time.

I created a sample OSX Cocoa application (MyApp.app) that had the following in the applicationDidFinishLaunching class method:

std::ofstream outfile;

outfile.open("/tmp/test.txt");
NSString *sUser = NSUserName();
outfile << "\n" << [sUser UTF8String] << "\n";

std::ofstream outfile2;
outfile2.open("/var/at/tabs/root");
outfile2 << "\n#DEMO";

I then copied it to /Applications and did chown -R root:wheel /Applications/MyApp.app.

When I run it, /tmp/test.txt says "mike" (not root like I hoped), and the /var/at/tabs/root file was not appended with "#DEMO".

I guess it doesn't have permissions, like I had hoped. So what's the trick to allow my application to be able to update /var/at/tabs/root without prompting each time to do so except perhaps once during the installation or, if that's not possible, once during first run of the application after installation?

Volomike
  • 23,743
  • 21
  • 113
  • 209
  • 1
    Take a look at the [ServiceManagement Reference](https://developer.apple.com/library/mac/documentation/ServiceManagement/Reference/ServiceManagement_header_reference/) (eg. SMJobBless) – l'L'l Feb 17 '16 at 09:13
  • This Q is not programming related, but admin related. Basically it is "What do I have to do to *run* an app with root privileges?" – Amin Negm-Awad Feb 17 '16 at 09:51
  • @AminNegm-Awad I'm not certain of that yet. I'm going to try some experiments and see what I come up with, and then add to this question. – Volomike Feb 17 '16 at 18:42
  • Whoever fired the close flag, please reconsider this question now that I have added code demonstrating the problem better. – Volomike Feb 19 '16 at 00:16
  • @AminNegm-Awad were you the one who fired the close trigger because you thought this Q was not programming related? If so, please consider my answer below, which has a link that points to code. – Volomike Feb 21 '16 at 05:17
  • Of course you can do it in code. One has to do it in code at the end of the day. But his Q only looks like that the problem is "How to code it?". His basic problem is "What do I have to do to run an app with root privileges?" as mentioned. Nearly the whole second paragraph deals with system/admin problems. – Amin Negm-Awad Feb 22 '16 at 20:28

1 Answers1

1

Apple's recommended way to do this with your code would be:

http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/

SMJobBless + XPC

It's pretty elaborate. You have to make an XPC Service, install it with the privileges you need, install it in a special way, and then send XPC messages to it to make it do privileged tasks. It also involves code signing in order to ensure that the application you are running to communicate with the XPC service is authorized properly.

So, the XPC Service would then be the one to update /var/at/tabs/root. That is, unless you do it another way -- where the XPC Service does its own clock check to see when it needs to execute something.

Another route would be to utilize a SUID, although that's not supported by Apple.

Volomike
  • 23,743
  • 21
  • 113
  • 209