AuthorizationExecuteWithPrivileges è deprecato

Dall’aggiornamento a OSX 10.7 Lion, Xcode mi dice che AuthorizationExecuteWithPrivileges è deprecato.

Qualcuno può suggerire un modo in cui la mia applicazione può scrivere in una directory per la quale non ha il permesso?

So che sembra pazzesco, ma in realtà funziona :

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

Sto eseguendo un Applescript da Objective C. L’unico svantaggio è che non è ansible ottenere privilegi di root permanenti con questo. Richiederà la password ogni volta che lo esegui.

Infatti, AuthorizationExecuteWithPrivileges() è stato deprecato per un tempo molto lungo, è solo di recente che il file di intestazione ha raggiunto questo fatto.

È ansible creare uno strumento di supporto privilegiato come parte della propria applicazione. È ansible utilizzare la funzione SMJobBless() ServiceManagement.framework per fare in modo che l’helper SMJobBless() distribuito nel contesto launchd sistema: quindi quando è necessario eseguire attività con privilegi, è sufficiente SMJobBless() un messaggio al helper con privilegi per eseguire tale operazione.

C’è un po ‘di complessità nascosta, in quanto l’app e l’helper devono dichiarare l’identity framework di firma dell’altro prima che SMJobBless() creda che SMJobBless() essere usati insieme, e bisogna che il linker scriva lo strumento di aiuto File Info.plist nel file binario. Tutto ciò è coperto dalla Documentazione di Apple e Apple ha fornito anche un progetto di esempio .

Ho scritto un’applicazione di esempio che utilizza SMJobBless() per distribuire il suo helper privilegiato.

Sulla base di una grande scoperta di user950473 ho implementato la sua scoperta come metodo; pensavo di condividere il codice nel caso fosse utile.

 - (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; } } 

Esempio di utilizzo:

  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 } 

È un po ‘hacky, ma IMHO è una soluzione soddisfacente.

AuthorizationExecuteWithPrivileges è in effetti deprecato .
Ma fortunatamente, c’è un nuovo modo consigliato di procedere.

A partire da 10.6 c’è la nuova API e si consiglia di installare uno strumento di supporto che eseguirà l’operazione privilegiata. Apple fornisce un esempio di codice che dimostra chiaramente come gestirlo.

Assicurati di dare un’occhiata al loro readme.txt dato che, contrariamente ad altri esempi di codice, c’è molto altro da fare che scaricare semplicemente il progetto ed eseguirlo.

Dall’introduzione di esempio SMJobBless

SMJobBless dimostra come installare in modo sicuro uno strumento di supporto che esegue un’operazione privilegiata e come associare lo strumento a un’applicazione che lo richiama.

A partire da Snow Leopard, questo è il metodo preferito per gestire l’escalation dei privilegi su Mac OS X e dovrebbe essere utilizzato al posto di approcci precedenti come BetterAuthorizationSample o chiamando direttamente AuthorizationExecuteWithPrivileges .

SMJobBless utilizza ServiceManagement.framework introdotto in Mac OS X v10.6 Snow Leopard.

Fonte: esempio di codice Apple SMJobBless