获取管理员权限以使用来自Cocoa应用程序的rm删除文件

For*_*orm 10 privileges cocoa authorization keychain nstask

我正在制作一个删除日志文件的小应用程序.我正在使用一个运行rm和srm(secure rm)的NSTask实例来删除文件.

我希望能够删除以下文件:

  • /图书馆/日志
  • 〜/资源库/日志

问题是用户帐户无权访问系统库文件夹中的某些文件,例如Adobe日志子文件夹和其他文件.例如,只有"system"用户(组?)对Adobe logs文件夹及其内容具有r/w权限,并且当前用户甚至没有在文件夹的"获取信息"窗口中显示的权限中的条目.

我希望能够完全做到:

  1. 获得管理员权限.
  2. 将密码存储在钥匙串中,这样每次应用程序都不必唠叨用户(密码存储是个坏主意吗?可能吗?)
  3. 删除文件权限的文件.

我正在使用NSTask,因为它提供任务完成通知,从任务本身获取文本输出等.我需要使用其他东西吗?如果是这样,在运行具有管理员权限的rm和srm时,如何复制NSTask的完成通知和输出文件句柄?

我正在寻找最安全的方式来处理这种情况.即我不希望我的应用程序成为特权升级攻击的门户.

我查看了授权服务编程指南,但我不确定哪种情况适合.起初我认为这AuthorizationExecuteWithPrivileges是一个好主意,但在阅读了更多有关该主题的内容后,出于安全原因,不建议使用此方法.

非常欢迎详细的答案.我相信你们中的一些人已经不得不做类似的事情,并且需要分享一些代码和知识.

提前致谢!

更新:

我现在能够弹出身份验证对话框并获取权限,如下所示:

OSStatus status;
AuthorizationRef authRef;
    status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);

AuthorizationRights authRights;
AuthorizationItem authItems[1];

authItems[0].name = kAuthorizationRightExecute;

authRights.count = sizeof(authItems) / sizeof(authItems[0]);
authRights.items = authItems;

AuthorizationFlags authFlags = kAuthorizationFlagDefaults | kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed;

status = AuthorizationCopyRights(authRef, &authRights, kAuthorizationEmptyEnvironment, authFlags, NULL);
Run Code Online (Sandbox Code Playgroud)

从它的外观来看,似乎"Factored Application"方法看起来最合适.问题是,对我而言,rm似乎已经成为一个外部辅助工具了.我不确定我是否获得了文档中建议的setuid替代方案.我可以在rm上设置setuid位并使用我已实现的NSTask方法运行它吗?这意味着我不需要创建自己的帮助工具.有人可以详细说明这个问题吗?

我还查看了BetterAuthorizationSample,它被建议作为setuid位方法的一种更安全和最新的替代方法,但发现它非常复杂,例如简单的行为.任何提示?

在此先感谢您的帮助!

And*_*rei 9

也许有点晚了,但这可能对其他人的未来参考有用.大部分代码都来自此人.

基本上,它与Mac上的授权有很大关系.您可以在这里这里阅读更多相关信息.

代码,使用rm工具:

+ (BOOL)removeFileWithElevatedPrivilegesFromLocation:(NSString *)location
{
    // Create authorization reference
    OSStatus status;
    AuthorizationRef authorizationRef;

    // AuthorizationCreate and pass NULL as the initial
    // AuthorizationRights set so that the AuthorizationRef gets created
    // successfully, and then later call AuthorizationCopyRights to
    // determine or extend the allowable rights.
    // http://developer.apple.com/qa/qa2001/qa1172.html
    status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Error Creating Initial Authorization: %d", status);
        return NO;
    }

    // kAuthorizationRightExecute == "system.privilege.admin"
    AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0};
    AuthorizationRights rights = {1, &right};
    AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
                                kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;

    // Call AuthorizationCopyRights to determine or extend the allowable rights.
    status = AuthorizationCopyRights(authorizationRef, &rights, NULL, flags, NULL);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Copy Rights Unsuccessful: %d", status);
        return NO;
    }

    // use rm tool with -rf
    char *tool = "/bin/rm";
    char *args[] = {"-rf", (char *)[location UTF8String], NULL};
    FILE *pipe = NULL;

    status = AuthorizationExecuteWithPrivileges(authorizationRef, tool, kAuthorizationFlagDefaults, args, &pipe);
    if (status != errAuthorizationSuccess)
    {
        NSLog(@"Error: %d", status);
        return NO;
    }

    // The only way to guarantee that a credential acquired when you
    // request a right is not shared with other authorization instances is
    // to destroy the credential.  To do so, call the AuthorizationFree
    // function with the flag kAuthorizationFlagDestroyRights.
    // http://developer.apple.com/documentation/Security/Conceptual/authorization_concepts/02authconcepts/chapter_2_section_7.html
    status = AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

  • 此方法使用10.7中不推荐使用的`AuthorizationExecuteWithPrivileges` (6认同)

Joh*_*her 4

几个月前我也曾有过这样的头痛。我试图让一个以管理员权限运行的 shell 脚本在某个时间关闭我的计算机。我感受到你的痛苦。

我使用了 BetterAuthorizationSample,这完全是一场噩梦。但我采取了最务实的路线 - 我没有费心去理解正在发生的一切,我只是抓住了代码的核心。

我没花太长时间就让它做我想做的事。我不记得具体修改了什么,但欢迎您查看我的代码:

http://github.com/johngallagher/TurnItOff

我希望这对您寻求安全的应用程序有所帮​​助!