如何以root身份使用NSTask?

11 cocoa sudo root nstask

在我正在创建的应用程序中,我需要以root身份运行以下命令(如果用户真的想要提示用户,并且将要求他们使用NSTask来解除他们的驱动器):

/bin/rm -rf /
#Yes, really
Run Code Online (Sandbox Code Playgroud)

问题是简单地使用替换用户Do(sudo)不起作用,因为用户需要输入密码到不可用的标准输入.当你点击Preferences.app中的锁时,我宁愿向用户显示你所看到的同一个窗口,这样(希望密码较短):

截图http://www.quickpwn.com/wp-content/uploads/2009/08/snow-leopard-enter-password.png


谁能帮我这个?谢谢.

svt*_*vth 9

查看STPrivilegedTask,这是一个围绕AuthorizationExecuteWithPrivileges()的Objective-C包装类,具有类似NSTask的接口.

  • 谢谢:简单,工作,只是优雅的解决方案! (2认同)

Geo*_*lly 6

这是在Mac OS X上正确执行的最难的任务之一.

有关如何执行此操作的指南是" 授权服务编程指南".有多种可能性,通常最安全的是最难实现的.

我已经开始编写一个使用launchd守护程序的工具(最安全的方式),代码可以在谷歌代码上找到.因此,如果您愿意,可以复制该代码.


Car*_*s P 5

我想我现在可以回答这个问题,这要归功于谷歌搜索和这个SO问题的很好发现。这有点hacky,但是恕我直言是一个令人满意的解决方案。

我写了这个通用实现,应该可以实现您想要的:

- (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;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

    NSString * output = nil;
    NSString * processErrorDescription = nil;
    BOOL success = [self runProcessAsAdministrator:@"/usr/bin/id"
                    withArguments:[NSArray arrayWithObjects:@"-un", nil]
                           output:&output
                            errorDescription:&processErrorDescription
                  asAdministrator:YES];


    if (!success) // Process failed to run
    {
         // ...look at errorDescription 
    }
    else
    {
         // ...process output
    }
Run Code Online (Sandbox Code Playgroud)