Authorization Services?

Discussion in 'Mac Programming' started by RobRiley, Feb 24, 2009.

  1. RobRiley macrumors member

    Feb 4, 2009

    I'm making a cocoa app that needs to execute shell scripts as root/sudo, feed the output to a log drawer and handle any authentication requests. The app is basically a gui for a bunch of shell scripts that are already written, tried and tested. Normally I would run sudo /usr/local/myApp/ in terminal, enter root password and just sit back and enjoy the output :) Instead I want to select 'myScript' from a cocoa menu, enter a root or admin password in a prompt box and enjoy that same output in a log drawer.

    Will Authorization Services handle the authentication in this way? And can it also feed the output back? Or should I use something else? Also if within my scripts I was ssh'ing to another machine as root, could I bring up a password prompt for that too?

    As you may have guessed, I'm pretty new to this so any help is massively appreciated.

    Thanks very much.

  2. Sayer macrumors 6502a


    Jan 4, 2002
    Austin, TX
    I think there already exists an app to make a GUI version of a shell script, might save some time to google for one.

    Also if you want to login to a remote machine you can use the scripting of 'expect' instead of regular shell scripting. Its like an interactive scripting system, very easy to get the hang of quickly.

    Here's a sample:

    #!/usr/bin/expect --
    spawn /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --associate=[lrange $argv 0 0]
    expect {
    	WPA {
    		send "[lrange $argv 1 1]"
    		send "\r"
    		send_user "Connected [lrange $argv 0 0]"
    	} sorry {
    		send_user "Wrong Password"
    The "WPA" part is pattern matching of the result of running the command. If "WPA" is found, then the bracketed part is executed, if "sorry" is found instead, that part runs. And in both cases a text result is sent back up the call chain.

    [lrange $argv 0 0]
    part gets the first argument passed in to the script to then use with the tool as an input parameter.
  3. RobRiley thread starter macrumors member

    Feb 4, 2009
    Thanks for the info. I've taken a look at dropscript but it doesn't really do what I need - I'm actually just working on part of a more complex app with several scripts and functions etc.

    Does anyone know if I can achieve what I want with NSTask or Authorization Services? Or a combination of both?
  4. kainjow Moderator emeritus


    Jun 15, 2000
    Check out the AuthorizationExecuteWithPrivileges() function.
  5. RobRiley thread starter macrumors member

    Feb 4, 2009
    Thanks - yes I already started to look at this. A question - say I have a shell script that must be run as root or sudo - can AuthorizationExecuteWithPrivileges() execute the script as root/sudo and present the user with an authentication dialogue box for them to enter a password and allow the script to continue? And if my script involved ssh'ing to another machine, could it also handle the authentication there and deal with pausing/resuming the script in the background until the user has authenticated correctly?

    Thanks in advance.. Don't worry I'm not expecting a full demonstration/example - just want to know if I'm going down the right track :)

    Thanks again.
  6. kainjow Moderator emeritus


    Jun 15, 2000
  7. RobRiley thread starter macrumors member

    Feb 4, 2009

    I'm struggling with this a little. I've read the official Apple bit on this and while it makes sense, I'm struggling with what code to put where. In short, I want to be able to call and execute a script with root privileges from an IB button or menu. I'm pretty sure the following code covers everything I need to do but I need help to get it all working/in the right order.

    - (IBAction)RunScriptAsRoute:(id)sender;{
    	//create empty authorization reference - should this be in another file?
    	AuthorizationRef myAuthorizationRef; 
    	OSStatus myStatus; 
    	myStatus = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults,
    	//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 | 				
    	myStatus = AuthorizationCreate (&myRights, kAuthorizationEmptyEnvironment, 
            myFlags, &myAuthorizationRef);
    	//execute script here..????
    	//free the authorization
    	myStatus = AuthorizationFreeItemSet (myAuthorizedRights);
    Any help/suggestions/pointers or editing of this code will be much appreciated.

    Many thanks :)

Share This Page