2011-07-27 392 views

回答

31

实际上,AuthorizationExecuteWithPrivileges()已被弃用了很长一段时间,直到最近才有头文件赶上了这个事实。

您可以创建一个特权辅助工具作为您的应用程序的一部分。您可以使用ServiceManagement.frameworkSMJobBless()函数将帮助程序部署到系统launchd上下文中:然后,当您需要执行特权任务时,您只需向特权帮助程序发送消息以完成此项工作。

有一点隐藏的复杂性,因为应用程序和帮手必须各自声明另一个的签名标识,然后SMJobBless()认为它们应该一起使用,并且您需要让链接器编写帮助工具的Info.plist文件放入二进制文件中。这一切都覆盖了Apple's Documentation,苹果也提供了a sample project

I wrote an example application使用SMJobBless()来部署其特权助手。

+0

您好,感谢您的答复。如果AuthorizationExecuteWithPrivileges()已被弃用很长一段时间,它是否应该继续工作?基本上,自从Lion更新以后,这个应用程序停止工作,我认为这是因为它现在被标记为已弃用...应该事实上仍然有效,并且我的问题在别处?非常感谢 – Phill

+4

您不应该依赖'AuthorizationExecuteWithPrivileges()',这是一个可怕的安全漏洞。通过'SMJobBless()'完成你想要做的事。 – 2011-07-27 13:04:40

+0

@GrahamLee那么安装程序使用'AuthorizationExecuteWithPrivileges'如何?参考文献指出:“你应该只使用这个函数来允许安装程序以root身份运行,并允许setuid工具在丢失的情况下修复它的setuid位”,并且授权服务编程指南建议使用这个函数来启动安装程序(虽然它有点过时) 。在像命令行工具这样简单的应用程序中启动安装程序有没有其他选择? – cody

32

我知道这听起来很疯狂,但这种实际工作

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!"); 
} 

我从目的C.执行一个AppleScript唯一的缺点是,你不能获得与此永久root权限。每次运行时都会要求输入密码。

+5

你会看看那个。所以你'根'?!哦,等等,我是。不,等待.. _AppleScript is_?耶稣。这当然很疯狂。唯一会更疯狂的是,如果它没有要求你的密码,哈哈。 –

+0

我试图使用它,但它并没有要求我输入密码。相反,它只是跳到打印“失败!”当我打印错误描述时,我得到这个:“NSAppleScriptErrorMessage =”管理员用户名或密码不正确。“;” 这是在沙箱启用的应用程序...有没有人有建议,与沙箱启用应用程序的工作? – ArtOfWarfare

+1

供参考:如技术说明TN2065中所述:在AppleScript中执行shell脚本(http://developer.apple.com/library/mac/#technotes/tn2065/_index.html): 使用管理员权限,用户名和这样的密码参数: 做shell脚本“命令”用户名“我”密码“mypassword”具有管理员权限 – geowar

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 
    } 

这是非常轻微哈克,但恕我直言是一个令人满意的解决方案。

+1

如果脚本的路径中有空格,如果要运行应用程序捆绑软件中包含的脚本,则可能会失败。要解决这个问题,只需在将fullScript设置为@“'%@'%@”时更改格式,以便引用进程路径名。 – Jim

+1

谢谢 - 已在代码中解决了这个问题。 –

+0

嗨,有没有办法在密码提示中添加应用程序图标来代替解决方案中的空白文件? – Yann86

6

AuthorizationExecuteWithPrivileges确实已弃用
但幸运的是,有一种新的推荐方式来进行。

从10.6开始就有新的API,建议安装一个辅助工具来执行特权操作。 Apple提供了一个code sample,清楚地演示了如何管理它。

请确保您查看他们的readme.txt,因为与其他代码示例相反,除了下载项目并运行它之外,还有更多的工作要做。

从SMJobBless实例介绍

SMJobBless演示了如何安全地安装一个辅助工具,进行权限的操作,以及如何将工具 与调用它的应用程序相关联。

作为雪豹的,这是Mac OS X上的管理特权 升级和应该用于代替前面 方法的BetterAuthorizationSample或直接调用 AuthorizationExecuteWithPrivileges的优选方法。

SMJobBless使用Mac OS X v10.6 Snow Leopard中引入的ServiceManagement.framework。

来源:Apple SMJobBless code sample

+1

耻辱,要使用SMJobBless你需要一个付费的OSX开发人员ID ... –

+0

为什么你会这么说?今天我可以下载示例代码,使用我提供的链接和一个非付费开发者帐户。 – Jean

+3

您是否已成功运行项目?它需要使用OSX开发者帐户对应用程序进行代码签名。 –