2011-07-27 390 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開發者帳戶對應用程序進行代碼簽名。 –