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?
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With