Obtaining admin privileges to delete files using rm from a Cocoa app

后端 未结 2 424
臣服心动
臣服心动 2020-12-14 04:35

I am making a small app that deletes log files. I am using an NSTask instance which runs rm and srm (secure rm) to delete files.

I want to be able to delete files in

相关标签:
2条回答
  • 2020-12-14 04:53

    I had this headache a few months ago. I was trying to get a shell script running with admin privileges that shutdown my computer at a certain time. I feel your pain.

    I used the BetterAuthorizationSample which was a total nightmare to wade through. But I took the most pragmatic route - I didn't bother trying to understand everything that was going on, I just grabbed the guts of the code.

    It didn't take me that long to get it doing what I wanted. I can't remember exactly what I altered, but you're welcome to check out my code:

    http://github.com/johngallagher/TurnItOff

    I hope this helps on your quest for a secure application!

    0 讨论(0)
  • 2020-12-14 05:12

    Perhaps a tad late, but this might be useful for future reference for other people. Most of the code is from this person.

    Basically, it has a lot to do with Authorization on the Mac. You can read more about that here and here.

    The code, which uses the rm tool:

    + (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;
    }
    
    0 讨论(0)
提交回复
热议问题