Call Executable with Root Privileges from IB Button or Menu

Discussion in 'Mac Programming' started by RobRiley, Apr 4, 2009.

  1. macrumors member

    Joined:
    Feb 4, 2009
    Location:
    London
    #1
    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.

    Code:
    - (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.
     
  2. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    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.
     
  3. macrumors regular

    jtibbitt

    Joined:
    Jan 3, 2009
    #3
    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
     
  4. thread starter macrumors member

    Joined:
    Feb 4, 2009
    Location:
    London
    #4
  5. thread starter macrumors member

    Joined:
    Feb 4, 2009
    Location:
    London
    #5
    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..
     
  6. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #6
    Hold onto the authorization item set you create and re-use it. Recreate them if they become invalid.
     
  7. thread starter macrumors member

    Joined:
    Feb 4, 2009
    Location:
    London
    #7
    Thanks - so I do I just omit releasing it until the app quits?
     
  8. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #8
    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.
     
  9. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    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
     
  10. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #10
    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.
     

Share This Page