不推荐使用AuthorizationExecuteWithPrivileges

时间:2011-07-27 09:11:56

标签: objective-c xcode macos

自从更新到OSX 10.7 Lion后,Xcode告诉我AuthorizationExecuteWithPrivileges已被弃用。

有人可以建议我的应用程序可以写入一个它没有权限的目录吗?

4 个答案:

答案 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。

来源:Apple SMJobBless code sample