问题
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?
回答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.
来源:https://stackoverflow.com/questions/35452209/update-root-crontab-with-objective-c