PDA

View Full Version : Call Executable with Root Privileges from IB Button or Menu




RobRiley
Apr 4, 2009, 04:21 AM
Hi,

Apologies for the sort of double-posting here - I previously tagged this onto the end of an old thread but I think it went slightly off topic so I decided to start a new one. I'm pretty sure other people would find this useful anyway.

So I have some shell scripts that need to run as root and I want to be able to call them from within my app, present the user with an authentication box and run the script feeding the output back to my app's window. I have thrown the following code together from Apple's documentation and would welcome feedback and suggestions on how I can actually make this work. I think most of the code is there, but with many mistakes and misunderstandings on my part.


- (IBAction)RunScriptAsRoute:(id)sender;{

//create empty authorization reference - should this be in another file?
AuthorizationRef myAuthorizationRef;
OSStatus myStatus;
myStatus = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults,
&myAuthorizationRef);

//set up rights and request authorization
AuthorizationItem myItems[1];
myItems[0].name = "com.mycompany.myapp.rootprivs";
myItems[0].valueLength = 0;
myItems[0].value = NULL;
myItems[0].flags = 0;
AuthorizationRights myRights;
myRights.count = sizeof (myItems) / sizeof (myItems[0]);
myRights.items = myItems;
AuthorizationFlags myFlags;
myFlags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagExtendRights;
myStatus = AuthorizationCreate (&myRights, kAuthorizationEmptyEnvironment,
myFlags, &myAuthorizationRef);

//execute script here..????

//free the authorization
myStatus = AuthorizationFreeItemSet (myAuthorizedRights);

}


Any help will be massively appreciated.

Many thanks.



kainjow
Apr 4, 2009, 10:14 AM
You need to use the AuthorizationExecuteWithPrivileges() function to actually run something with the privileges setup. Search around with this function, you'll find lots of sample code. Also search code.google.com - some nice examples there.

jtibbitt
Apr 5, 2009, 04:11 AM
Don't know if this will help. But if you are talking about UNIX shell scripts, then inside the script, you can run any command as root (noninteractively) as follows:

#!/bin/bash
echo 'mypassword' | sudo -S mkdir /usr/newdirectory
echo 'mypassword' | sudo -S chmod 777 /usr/newdirectory
exit 0

RobRiley
Apr 7, 2009, 04:29 PM
Hi,

Thanks for the help. I found a really good example here for anyone else needing it:

http://code.google.com/p/eavesdrop/source/browse/branches/v0.6/Authorization.m?spec=svn52&r=52

Cheers :)

RobRiley
Apr 14, 2009, 03:08 PM
Carrying on.. I've got the basics of this working but the app I'm writing performs several privileged operations. Is it possible to prompt for authorization once when an app opens so anything for the entire session (or a set period of time) executes as root? I think I've seen this in other apps..

Krevnik
Apr 14, 2009, 03:16 PM
Carrying on.. I've got the basics of this working but the app I'm writing performs several privileged operations. Is it possible to prompt for authorization once when an app opens so anything for the entire session (or a set period of time) executes as root? I think I've seen this in other apps..

Hold onto the authorization item set you create and re-use it. Recreate them if they become invalid.

RobRiley
Apr 14, 2009, 03:22 PM
Hold onto the authorization item set you create and re-use it. Recreate them if they become invalid.

Thanks - so I do I just omit releasing it until the app quits?

Krevnik
Apr 14, 2009, 03:29 PM
Thanks - so I do I just omit releasing it until the app quits?

Well, that really depends. I've not needed to run sub-processes as root in my own work so I don't know how long credentials last before they auto-expire.

You'd hold a reference to them in a class, and release them when the class is dealloc'd. You would also probably want to check to see if they are valid or not before using them (beyond just a nil check), as they may auto-expire even if you hold onto them.

lee1210
Apr 14, 2009, 03:36 PM
i know nothing of the technical aspects, but i would treat this like preference panes do... don't let the user do anything privileged until they click the "padlock" and enter their credentials. Once this has been done, allow privileged operations to be performed. If the user doesn't want to allow any further privileged operations, they can click the padlock, and you'll discard the "token" allowing privileged operations and prevent the user from attempting any until they reauthenticate.

-Lee

Krevnik
Apr 14, 2009, 03:42 PM
i know nothing of the technical aspects, but i would treat this like preference panes do... don't let the user do anything privileged until they click the "padlock" and enter their credentials. Once this has been done, allow privileged operations to be performed. If the user doesn't want to allow any further privileged operations, they can click the padlock, and you'll discard the "token" allowing privileged operations and prevent the user from attempting any until they reauthenticate.

-Lee

I like this idea as well. If you are targeting 10.5 and later, I believe there are even controls meant to make the padlock easier to implement.