自从更新到OSX 10.7 Lion后,Xcode告诉我AuthorizationExecuteWithPrivileges
已被弃用。
有人可以建议我的应用程序可以写入一个它没有权限的目录吗?
答案 0 :(得分:34)
事实上,AuthorizationExecuteWithPrivileges()
已经被弃用很长一段时间了,直到最近头文件才赶上了这个事实。
您可以创建特权帮助工具作为应用程序的一部分。您可以使用ServiceManagement.framework
的{{1}}函数将帮助程序部署到系统SMJobBless()
上下文中:然后当您需要执行特权任务时,您只需向特权帮助程序发送消息即可完成该工作
有一点隐藏的复杂性,因为应用程序和帮助程序必须在launchd
认为它们应该一起使用之前声明另一个的签名标识,并且您需要获取链接器将辅助工具的SMJobBless()
文件写入二进制文件。这一切都由Apple's Documentation涵盖,Apple也提供了a sample project。
我wrote an example application使用Info.plist
部署其特权助手。
答案 1 :(得分:33)
我知道这听起来很疯狂,但实际上有效:
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!");
}
我正在从Objective C执行Applescript。唯一的缺点是你无法获得永久的root权限。每次运行时都会要求输入密码。
答案 2 :(得分:17)
根据user950473的一个很好的发现,我已经将他/她的发现作为一种方法实现了;以为我会分享这些代码以防它有用。
- (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;
}
}
用法示例:
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
}
这是非常轻微的hacky,但恕我直言是一个令人满意的解决方案。
答案 3 :(得分:6)
AuthorizationExecuteWithPrivileges 。
但幸运的是,有一种新的推荐方法可以继续。
从10.6开始,有新的API,建议安装一个将执行特权操作的帮助工具。 Apple提供code sample,清楚地演示了如何管理它。
请确保查看他们的readme.txt,因为与其他代码示例相反,除了下载项目并运行它之外,还有更多工作要做。
来自SMJobBless示例介绍
SMJobBless 演示如何安全地安装执行特权操作的帮助工具以及如何关联该工具 使用调用它的应用程序。
从Snow Leopard开始,这是管理权限的首选方法 Mac OS X上的升级和之前的应该使用 诸如 BetterAuthorizationSample 之类的方法或直接调用 的 AuthorizationExecuteWithPrivileges 强>
SMJobBless使用Mac中引入的ServiceManagement.framework OS X v10.6 Snow Leopard。