Since updating to OSX 10.7 Lion, Xcode tells me that AuthorizationExecuteWithPrivileges
is deprecated.
Can anyone suggest a way my application can write to a directory it doesn't have permission for?
Since updating to OSX 10.7 Lion, Xcode tells me that AuthorizationExecuteWithPrivileges
is deprecated.
Can anyone suggest a way my application can write to a directory it doesn't have permission for?
In fact, AuthorizationExecuteWithPrivileges()
has been deprecated for a very long time, it's only recently that the header file has caught up with this fact.
You can create a privileged helper tool as part of your application. You can use ServiceManagement.framework
's SMJobBless()
function to have the helper deployed into the system launchd
context: then when you need to perform privileged tasks, you just message the privileged helper to do that work.
There's a little bit of hidden complexity, in that the app and the helper must each declare the signing identity of the other before SMJobBless()
believes they're supposed to be used together, and you need to get the linker to write the helper tool's Info.plist
file into the binary. That's all covered by Apple's Documentation and Apple have provided a sample project, too.
I wrote an example application that uses SMJobBless()
to deploy its privileged helper.
AuthorizationExecuteWithPrivileges()
, it's a horrendous security hole. The way to do what you want to do is with SMJobBless()
. –
Weihs AuthorizationExecuteWithPrivileges
for the installer? Reference says that "You should use this function only to allow installers to run as root and to allow a setuid tool to repair its setuid bit if lost" and Authorization Services Programming Guide suggests to use this function to launch installers (although it somewhat outdated). Is there any alternative to launch installer in simple application like command line tool? –
Murrelet installer
utility on it? How can I do that without using deprecated functionality. Can I use system utilities as helper tool? I understand that I can launch installer with NSWorkspace class. But I don't need a GUI installer app, I want to do it quietly and I need an install process exit code, so I need to wait for it. What can you suggest in such case? –
Murrelet installer
as root
from a privileged helper tool using posix_spawn
–
Edmead NSFileManager
to delete /Applications/MyApplication.app
folder and some app data in ~/Library/Application Support/my.app/
–
Sun AuthorizationExecuteWithPrivileges()
? And the reference docs for SMJobBless()
say that it's deprecated now, too :( What's the replacement in 2022? developer.apple.com/documentation/servicemanagement/… –
Reinke I know it sounds crazy, but this actually works:
NSDictionary *error = [NSDictionary new];
NSString *script = @"do shell script \"whoami > /tmp/me\" with administrator privileges";
NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script];
if ([appleScript executeAndReturnError:&error]) {
NSLog(@"success!");
} else {
NSLog(@"failure!");
}
I'm executing an Applescript from Objective C. The only disadvantage is that you cannot gain permanent root privileges with this. It will ask for the password each time you run this.
root
?! Oh wait, I am. No, wait.. AppleScript is? Jesus. That is certainly crazy. The only thing that would be crazier is if it didn't ask for your password, lol. –
Barium % osascript -e 'do shell script "/bin/sh ./hello.sh" with administrator privileges'
errors with the following message: 0:82: execution error: /bin/sh: ./hello.sh: Operation not permitted (126)
. However the same command runs successfully if the with administrator privileges
portion is omitted from AppleScript. (P.S. The script hello.sh has required r/w/x permissions, etc.) –
Clougher Based on a great find by user950473 I've implemented his/her discovery as a method; thought I'd share the code in case it's helpful.
- (BOOL) runProcessAsAdministrator:(NSString*)scriptPath
withArguments:(NSArray *)arguments
output:(NSString **)output
errorDescription:(NSString **)errorDescription {
NSString * allArgs = [arguments componentsJoinedByString:@" "];
NSString * fullScript = [NSString stringWithFormat:@"'%@' %@", scriptPath, allArgs];
NSDictionary *errorInfo = [NSDictionary new];
NSString *script = [NSString stringWithFormat:@"do shell script \"%@\" with administrator privileges", fullScript];
NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:script];
NSAppleEventDescriptor * eventResult = [appleScript executeAndReturnError:&errorInfo];
// Check errorInfo
if (! eventResult)
{
// Describe common errors
*errorDescription = nil;
if ([errorInfo valueForKey:NSAppleScriptErrorNumber])
{
NSNumber * errorNumber = (NSNumber *)[errorInfo valueForKey:NSAppleScriptErrorNumber];
if ([errorNumber intValue] == -128)
*errorDescription = @"The administrator password is required to do this.";
}
// Set error message from provided message
if (*errorDescription == nil)
{
if ([errorInfo valueForKey:NSAppleScriptErrorMessage])
*errorDescription = (NSString *)[errorInfo valueForKey:NSAppleScriptErrorMessage];
}
return NO;
}
else
{
// Set output to the AppleScript's output
*output = [eventResult stringValue];
return YES;
}
}
Usage example:
NSString * output = nil;
NSString * processErrorDescription = nil;
BOOL success = [self runProcessAsAdministrator:@"/usr/bin/id"
withArguments:[NSArray arrayWithObjects:@"-un", nil]
output:&output
errorDescription:&processErrorDescription];
if (!success) // Process failed to run
{
// ...look at errorDescription
}
else
{
// ...process output
}
It's very slightly hacky, but IMHO is a satisfactory solution.
AuthorizationExecuteWithPrivileges is indeed deprecated.
But fortunately, there is a new recommended way to proceed.
As of 10.6 there is the new API and it is recommended to install a helper tool that will perform the privileged operation. Apple provide a code sample that clearly demonstrate how to manage it.
Make sure you check out their readme.txt since contrarily to other code sample there is more to do than just downloading the project and running it.
From The SMJobBless example introduction
SMJobBless demonstrates how to securely install a helper tool that performs a privileged operation and how to associate the tool with an application that invokes it.
As of Snow Leopard, this is the preferred method of managing privilege escalation on Mac OS X and should be used instead of earlier approaches such as BetterAuthorizationSample or directly calling AuthorizationExecuteWithPrivileges.
SMJobBless uses ServiceManagement.framework that was introduced in Mac OS X v10.6 Snow Leopard.
Source: Apple SMJobBless code sample
© 2022 - 2024 — McMap. All rights reserved.