2011-07-27 39 views
31

OSX 10.7 Lionにアップデートして以来、XcodeはAuthorizationExecuteWithPrivilegesが推奨されなくなったと伝えています。AuthorizationExecuteWithPrivilegesは非推奨です

誰でも私のアプリケーションが許可のないディレクトリに書き込む方法を提案できますか?

答えて

31

実際、AuthorizationExecuteWithPrivileges()は非常に長い間非難されていましたが、最近ではヘッダーファイルがこの事実に追いついています。

アプリケーションの一部として特権ヘルパーツールを作成できます。 ServiceManagement.frameworkSMJobBless()機能を使用して、システムにlaunchdコンテキストを展開することができます。次に、特権タスクを実行する必要がある場合は、特権ヘルパーにメッセージを送信してその作業を行います。

アプリとヘルパーがそれぞれSMJobBless()が一緒に使用されると信じる前に、相手の署名アイデンティティを宣言しなければならないという点で、やや複雑なことがあります。ヘルパーツールのInfo.plistファイルをバイナリに追加します。それはすべてApple's Documentationでカバーされ、Appleはa sample projectも提供しています。

I wrote an example applicationSMJobBless()を使用して特権ヘルパーを展開します。

+0

こんにちは、返信いただきありがとうございます。 AuthorizationExecuteWithPrivileges()が長期間使用されなくなった場合、引き続き動作する必要がありますか?基本的に、これはライオンのアップデート以来、私のアプリケーションでは動作しなくなりましたが、今は廃止予定とマークされているためだと思っていました...実際には機能していて問題は他にありますか?多くの感謝 – Phill

+4

あなたは 'AuthorizationExecuteWithPrivileges()'に頼るべきではありません、それは恐ろしいセキュリティホールです。あなたがしたいことをする方法は、 'SMJobBless()'で行います。 –

+0

@GrahamLeeそしてインストーラに 'AuthorizationExecuteWithPrivileges'を使用するのはどうですか?リファレンスは「インストーラをrootとして実行できるようにするためだけにこの関数を使用し、setuidツールがsetuidビットを紛失した場合に修復できるようにする必要がある」と述べ、Authorization Services Programming Guideはこの機能を使用してインストーラを起動することを提案しています。コマンドラインツールのような単純なアプリケーションでインストーラを起動する方法はありますか? – 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を実行していますが、あなたはこれで永久的なルート権限を取得することができないということです。これを実行するたびにパスワードを要求します。

+5

それを見ていますか?だから、あなたは 'ルート'ですか?ああ待って、私は。いいえ、待ってください.AppleScript is_?イエス。それは確かに狂っている。あなたのパスワードを尋ねなかった場合、狂っているのは唯一のことです。 –

+0

私はこれを使用しようとしましたが、私のパスワードを尋ねなかった。代わりに、単に「失敗!」という印刷にスキップしました。 "NSAppleScriptErrorMessage ="管理者のユーザー名またはパスワードが正しくありませんでした。 ";"エラーが発生しました。 これはサンドボックスが有効になっているアプリにあります...サンドボックス対応のアプリで作業する人はいますか? – ArtOfWarfare

+1

FYI:テクニカルノートTN2065に記載されているように、AppleScriptでシェルスクリプトを実行してください(http://developer.apple.com/library/mac/#technotes/tn2065/_index.html)。 管理者特権、ユーザー名、および 管理者権限を持つユーザー名 "me"パスワード "mypassword" – geowar

17

偉大なfind by 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があり、特権操作を実行するヘルパーツールをインストールすることをお勧めします。アップルはcode sampleを提供しています。

他のコードサンプルとは対照的に、プロジェクトをダウンロードして実行する以外にも、もっと多くのことがあるので、readme.txtをチェックアウトしてください。SMJobBless例の紹介から

SMJobBlessはしっかり特権操作とどのようにそれを呼び出すアプリケーションとツール を関連付けることを実行するヘルパーツールをインストールする方法を示しています。 Snow Leopardはのよう

、これは、Mac OS X上の特権 昇格を管理する好ましい方法であるとAuthorizationExecuteWithPrivilegesを呼び出す代わりになどとして以前 アプローチBetterAuthorizationSampleのか、直接使用する必要があります。

SMJobBlessは、Mac OSX v10.6 Snow Leopardで導入されたServiceManagement.frameworkを使用します。

出典:Apple SMJobBless code sample

+1

あなたは有料のOSX開発者IDが必要なSMJobBlessを使用することを恥ずかしく思っています... –

+0

なぜそれを言うでしょうか?私は、私が提供したリンクと無償の開発者アカウントを使用して、今日サンプルコードをダウンロードすることができました。 – Jean

+3

プロジェクトをまだ正常に実行しましたか?それはOSXの開発者アカウントでアプリケーションのコード署名を求めていた。 –