AuthorizationExecuteWithPrivileges устарела - PullRequest
34 голосов
/ 27 июля 2011

После обновления до OSX 10.7 Lion Xcode сообщает, что AuthorizationExecuteWithPrivileges устарела.

Может кто-нибудь предложить способ, которым мое приложение может записать в каталог, для которого у него нет разрешения?

Ответы [ 4 ]

34 голосов
/ 27 июля 2011

Фактически, AuthorizationExecuteWithPrivileges() устарел в течение очень долгого времени, только недавно этот заголовочный файл уловил этот факт.

Вы можете создать привилегированный вспомогательный инструмент как часть вашего приложения.,Вы можете использовать функцию ServiceManagement.framework SMJobBless() для развертывания помощника в системном контексте launchd: тогда, когда вам нужно выполнить привилегированные задачи, вы просто сообщаете привилегированному помощнику, чтобы выполнить эту работу.

Здесь есть небольшая скрытая сложность, в которой каждое приложение и помощник должны объявить удостоверение личности подписи другого, прежде чем SMJobBless() считает, что они должны использоваться вместе, и вам нужно заставить компоновщик написать помощникафайл Info.plist инструмента в двоичный файл.Это все описано в Документации Apple , и Apple предоставила и пример проекта .

Я написал пример приложения , в котором используется SMJobBless()развернуть своего привилегированного помощника.

33 голосов
/ 15 января 2012

Я знаю, это звучит безумно, но это на самом деле работает :

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

Я выполняю Applescript из Задачи C. Единственный недостаток - то, что вы не можете получить постоянные привилегии rootс этим.Он будет запрашивать пароль каждый раз, когда вы запускаете это.

17 голосов
/ 06 марта 2013

Основываясь на великолепной находке пользователя 950473, я реализовал его / ее обнаружение как метод;думал, что поделюсь кодом на случай, если он будет полезен.

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

Это очень хакерский вариант, но IMHO - удовлетворительное решение

6 голосов
/ 24 марта 2013

AuthorizationExecuteWithPrivileges действительно не рекомендуется .Но, к счастью, есть новый рекомендуемый способ продолжить.

Начиная с 10.6, есть новый API, и рекомендуется установить вспомогательный инструмент, который будет выполнять привилегированную операцию.Apple предоставляет пример кода , который наглядно демонстрирует, как им управлять.

Убедитесь, что вы проверили их readme.txt , поскольку в отличие от другого примера кодаэто больше, чем просто загрузить проект и запустить его.

Из введения примера SMJobBless

SMJobBless демонстрируеткак безопасно установить вспомогательный инструмент, который выполняет привилегированную операцию, и как связать инструмент с приложением, которое его вызывает.

Начиная со Snow Leopard, это предпочтительный метод управления повышением привилегий в Mac OS X и следует использовать вместо более ранних подходов, таких как BetterAuthorizationSample или прямой вызов AuthorizationExecuteWithPrivileges .

SMJobBless использует ServiceManagement.framework, который был представлен в Mac OSX v10.6 Snow Leopard.

Источник: Apple SMJobБесплатный пример кода

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...