Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elevating to admin rights in Mac application

I am making a simple application that lets you quickly enter a shell command to be run. It works perfectly, however there is the problem of sudo commands. Currently, it detects a sudo command, and then I try and get it to bring up an authorization window for the user's password, exactly like you would see in Installer.

Here's the code once it detects it is a sudo command:

SFAuthorization *authorization = [[SFAuthorization alloc] initWithFlags:kAuthorizationFlagPreAuthorize rights:NULL environment:kAuthorizationEmptyEnvironment];
if ([authorization obtainWithRight:"com.mycompany.myapplication" flags:kAuthorizationFlagPreAuthorize error:nil]){
    //authorized, now run the command using NSTask.
}else{
    //fail
}

Now, as far as I know, this is totally and completely wrong. This is just what I pieced together from the documentation. Any ideas?

like image 942
LukeWarm74 Avatar asked Sep 13 '09 02:09

LukeWarm74


3 Answers

You'll want to use the AuthorizationExecuteWithPrivileges function, like this:

- (IBAction)touch: (id) sender {

  NSString * filepath = [_filepathfield stringValue];
  FILE *commpipe = NULL;
  OSStatus execstatus;


  NSLog(@"file path is %@", filepath);

  char *args[] = {[filepath cString], NULL};


  SFAuthorization * authorization = [SFAuthorization authorization];

  execstatus = AuthorizationExecuteWithPrivileges([authorization authorizationRef],
                                                  "/usr/bin/touch",
                                                  kAuthorizationFlagDefaults,
                                                  args,
                                                  &commpipe);

  if (execstatus == errAuthorizationSuccess) 
    NSlog(@"Toot! It worked");
  else
    NSLog(@"No dice");

}

Given that BSD is a delicate and grumpy flower I'd recommend not letting a user execute commands arbitrary from the app as root.

/lecture

The code from your example is the beginnings of the way to go if you want to limit the functions of your own program from it's own users. For example, you might have an app that only lets certain users alter data from a saved file. So you'd create an entry in the security database 'com.mycompany.LibraryApp.AlterData' and check to see if the user has that privilege when they try to change the data. But that's a whole different topic...

Hope that helps, -p.

like image 197
Robert Daniel Pickard Avatar answered Sep 28 '22 14:09

Robert Daniel Pickard


I know it is a really old question, but to those still looking for an answer, here goes. (It uses AppleScript)

NSAppleScript *script = [[NSAppleScript alloc] initWithSource:@"do shell script \"[YOUR SCRIPT HERE]\" with administrator privileges"];

Of, course, replace [YOUR SCRIPT HERE] with your script, and be sure to escape the string, the cocoa way.

NSDictionary *errorInfo;
[script executeAndReturnError:&errorInfo];

For further explanation, please comment.

like image 29
dhruvit-r Avatar answered Sep 28 '22 16:09

dhruvit-r


Security is hard. I could paraphrase the documentation and provide code snippets, but I would likely be wrong. Worse, even if my high level descriptions were right, there would most likely be a tiny bug in the code snippets that would kill security.

If you are going to mess with privilege escalation, the best approach is to read the docs and use the provided samples.

https://developer.apple.com/mac/library/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html#//apple_ref/doc/uid/TP30000995-CH204-TP1

like image 29
bbum Avatar answered Sep 28 '22 16:09

bbum