0

As far as I can tell, this code should be running my script with elevated permission, but the NSTask doesn't seem to ever actually launch. I'm relatively new to Objective-C and Cocoa so I'm probably missing something simple here but either way I'm at a loss as to why this won't work.

CFErrorRef error;
AuthorizationItem authItem = { kSMRightBlessPrivilegedHelper, 0, NULL, 0 };
AuthorizationRights authRights = { 1, &authItem };
AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
AuthorizationRef auth;

if(AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, &auth) == errAuthorizationSuccess)
{
    NSString* myLabel = @"com.hidden.backup";
    (void) SMJobRemove( kSMDomainSystemLaunchd, (__bridge CFStringRef)myLabel, auth, false, NULL );

    NSString *path = [[NSBundle mainBundle] pathForResource:@"kandorBackup" ofType:@"sh"];
    NSPipe *outputPipe = [NSPipe pipe];
    readHandle = [outputPipe fileHandleForReading];
    inData = nil;
    returnValue = nil;

    NSTask *task = [[NSTask alloc] init];
    [task setLaunchPath:path];
    [task setArguments:[NSArray arrayWithObjects:login, selectedDrive, rsyncFinalFlags, nil]];
    [task setStandardOutput:outputPipe];
    [readHandle waitForDataInBackgroundAndNotify];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(recievedData:)
                                                 name:NSFileHandleDataAvailableNotification
                                               object:nil];

    SMJobSubmit( kSMDomainSystemLaunchd, (__bridge CFDictionaryRef)task, auth, &error);
}

If it helps, I am getting these two errors in the Xcode debugging area:

2014-08-04 11:44:39.169 <hidden>[68065:303] -[NSConcreteTask objectForKey:]: unrecognized selector sent to instance 0x600000099d70
2014-08-04 11:44:39.169 <hidden>[68065:303] Exception detected while handling key input.
Sam W
  • 599
  • 2
  • 16

1 Answers1

1

SMJobSubmit is not for elevating a NSTask. You rather you would construct an NSDictionary in the same format as a LaunchDaemon/LaunchAgent plist file and pass that NSDictionary to SMJobSubmit.

you'd do this

NSDictionary *dictionary = @{@"ProgramArguments": @[path,login, selectedDrive, rsyncFinalFlags]};
SMJobSubmit( kSMDomainSystemLaunchd, (__bridge CFDictionaryRef)dictionary, auth, &error);

unfortunately you won't get any progress messages back, if that's imperative you'll need to build a privileged helper tool and execute the NSTask from there.

https://developer.apple.com/library/mac/samplecode/EvenBetterAuthorizationSample/Listings/Read_Me_About_EvenBetterAuthorizationSample_txt.html

The Pulsing Eye
  • 161
  • 3
  • 11