AuthorizationExecuteWithPrivileges está obsoleto

Desde a atualização para o OSX 10.7 Lion, o Xcode me diz que AuthorizationExecuteWithPrivileges está obsoleto.

Alguém pode sugerir uma maneira pela qual meu aplicativo pode gravar em um diretório para o qual não tenha permissão?

Eu sei que parece loucura, mas isso realmente funciona :

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

Estou executando um Applescript do Objective C. A única desvantagem é que você não pode obter privilégios de root permanentes com isso. Ele pedirá a senha toda vez que você executar isso.

Na verdade, AuthorizationExecuteWithPrivileges() foi preterido por um tempo muito longo, é só recentemente que o arquivo de header alcançou esse fato.

Você pode criar uma ferramenta auxiliar privilegiada como parte de seu aplicativo. É possível usar a function SMJobBless() ServiceManagement.framework para que o auxiliar seja implantado no contexto launchd do sistema: em seguida, quando você precisar executar tarefas privilegiadas, basta enviar uma mensagem ao auxiliar privilegiado para fazer esse trabalho.

Há um pouco de complexidade oculta, em que o aplicativo e o ajudante devem declarar a identidade de assinatura do outro antes que o SMJobBless() acredite que eles devem ser usados ​​juntos, e você precisa fazer com que o vinculador escreva as ferramentas da ferramenta de ajuda. Arquivo Info.plist no binário. Tudo isso é coberto pela Documentação da Apple e a Apple também forneceu um projeto de amostra .

Eu escrevi um aplicativo de exemplo que usa o SMJobBless() para implantar seu auxiliar privilegiado.

Baseado em um ótimo achado por user950473 eu implementei sua descoberta como um método; pensei em compartilhar o código caso seja útil.

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

Exemplo de uso:

  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 } 

É muito ligeiramente hacky, mas IMHO é uma solução satisfatória.

AuthorizationExecuteWithPrivileges é realmente obsoleto .
Mas, felizmente, há uma nova maneira recomendada de prosseguir.

A partir do 10.6 há a nova API e é recomendado instalar uma ferramenta auxiliar que executará a operação privilegiada. A Apple fornece um exemplo de código que demonstra claramente como gerenciá-lo.

Certifique-se de verificar o readme.txt, pois, ao contrário de outro exemplo de código, há mais a ser feito do que apenas baixar o projeto e executá-lo.

A partir da introdução do exemplo SMJobBless

O SMJobBless demonstra como instalar com segurança uma ferramenta auxiliar que executa uma operação privilegiada e como associar a ferramenta a um aplicativo que a invoca.

A partir do Snow Leopard, esse é o método preferido para gerenciar o escalonamento de privilégios no Mac OS X e deve ser usado em vez de abordagens anteriores, como BetterAuthorizationSample, ou diretamente para AuthorizationExecuteWithPrivileges .

O SMJobBless usa o ServiceManagement.framework que foi introduzido no Mac OS X 10.6 Snow Leopard.

Fonte: amostra de código Apple SMJobBless