2012-07-16 101 views
0

我試圖創建一個使用SMJobBless複製文件的授權,但我無法讓它工作。助手應用程序已成功授權,Job is available!消息出現在[self copyFile]方法之前,但copyFile始終失敗。如果有人能夠闡明我做錯了什麼,或者提供瞭如何使這項工作非常好的例子。Objective-C,授權無法執行功能

appDelegate.h

#import <Cocoa/Cocoa.h> 

@interface SMJobBlessAppController : NSObject { 
    IBOutlet NSTextField *_textField; 
} 

- (BOOL)blessHelperWithLabel:(NSString *)label error:(NSError **)error; 
- (void)copyFile; 

@end 

appDelegate.m

#import <ServiceManagement/ServiceManagement.h> 
#import <Security/Authorization.h> 
#import "appDelegate.h" 

@implementation SMJobBlessAppController 
- (void)applicationDidFinishLaunching:(NSNotification *)notification 
{ 
    NSError *error = nil; 
    if (![self blessHelperWithLabel:@"com.apple.bsd.SMJobBlessHelper" error:&error]) { 
     NSLog(@"Something went wrong!"); 
    } else { 
     /* At this point, the job is available. However, this is a very 
     * simple sample, and there is no IPC infrastructure set up to 
     * make it launch-on-demand. You would normally achieve this by 
     * using a Sockets or MachServices dictionary in your launchd.plist. 
     */ 
     NSLog(@"Job is available!"); 

     [self->_textField setHidden:false]; 

     [self copyFile]; 

    } 
} 

- (void)copyFile { 

    NSError *error = nil; 

    NSFileManager *fileManager = [[NSFileManager alloc] init]; 
    NSString *sourceFile = @"~/path/to/file.txt"; 
    NSString *destFile = @"~/Library/Application Support/myApp/file.txt"; 

    if ([fileManager copyItemAtPath:sourceFile toPath:destFile error:&error] == YES) { 
     NSLog (@"[FILE] Copied."); 
     // NSLog (@"Copy successful"); 
    } else { 
     NSLog (@"[FILE] Copy failed."); 
     NSLog (@" %@ %@",sourceFile, destFile); 
     // NSLog (@"Copy failed"); 
    } 

    [fileManager release]; 

    return; 
} 

- (BOOL)blessHelperWithLabel:(NSString *)label error:(NSError **)error; 
{ 
    BOOL result = NO; 

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

    AuthorizationRef authRef = NULL; 

    /* Obtain the right to install privileged helper tools (kSMRightBlessPrivilegedHelper). */ 
    OSStatus status = AuthorizationCreate(&authRights, kAuthorizationEmptyEnvironment, flags, &authRef); 
    if (status != errAuthorizationSuccess) { 
     NSLog(@"Failed to create AuthorizationRef, return code %i", status); 
    } else { 
     /* This does all the work of verifying the helper tool against the application 
     * and vice-versa. Once verification has passed, the embedded launchd.plist 
     * is extracted and placed in /Library/LaunchDaemons and then loaded. The 
     * executable is placed in /Library/PrivilegedHelperTools. 
     */ 
     result = SMJobBless(kSMDomainSystemLaunchd, (CFStringRef)label, authRef, (CFErrorRef *)error); 
    } 

    return result; 
} 
@end 

回答

1

你完全缺失的SMJobBless點。它不會神奇地讓你的當前應用程序能夠做特權的事情。相反,它會安裝並運行一個單獨的幫助工具,該工具允許執行特權事件,但不應該做任何其他事情(儘可能少)。

您需要將copyFile中的代碼移動到the main function in SMJobBlessHelper.c。 (因爲這是一個C文件,你必須用C重寫它 - 也許使用CoreFoundation - 或者你必須改變工具來使用Objective-C。沒有人說這很容易。)

+0

我認爲這更多的是一個不完全知道如何或爲什麼如此困難的例子。我在任何地方都找不到答案,這些答案能夠讓我們知道如何使用提升的權限複製文件。我創建了很多(.pkg)安裝程序包,顯然需要授權,而且非常簡單 - 爲什麼這應該與以前有所不同? – 2012-07-17 01:24:29

+0

您如何看待安裝程序系統實際上覆制文件?這不是魔術 - 它內部的代碼與你想要做的事很相似。這不是一項根本簡單的操作,只是您習慣於爲您完成所有工作的系統。 – 2012-07-17 01:35:40

+0

我發佈了這個問題,所以也許有人可以幫我弄清楚它是如何完成的,或者至少指導我一些有用的東西。顯然你比評判我更看重幫助。 – 2012-07-17 03:28:35