Mac OS X에서 System folder로 파일 카피할 때의 권한 문제

Unix에선 가능하면 시스템 폴더로 파일을 카피하지 않는게 좋다. 사실 모든 OS에서 다 그렇다. 이걸 안지키고 막가파식으로 간 OS가 바로 Windows이지 않는가? 아무 프로그램이나 Windows 디렉토리 내에 다 써대고 말이지..
하지만 가끔 필요할 때가 있다. 예를 들어 보자. Final Cut Pro의 plugin들은 /Library/Application Support/Final Cut Pro 어쩌구/Plugin에 들어간다. 만약 Plugin이 필요로하는 어떤 화일을 거기에다 넣어 놓는다고 하자. 그럼 그냥 카피를 해선 들어가지 않는다. 왜냐하면 거기에 파일을 생성하려면 Administrator의 권한이 필요하기 때문이다.

자 그럼 어떻게 하면 소스코드에서 파일 카피를 할때, 권한을 설정할까?
Mac에서는 여러가지 접근법이 있는데, 해당 프로세스의 권한을 올리기, 혹은 그 프로세스가 호출하는 다른 프로세스의 권한을 올리기 (근데 이때는 원래 caller process에서 pre-authorization이 필요하다.) 후자를 애플 문서에선 Factored program이라고 한다. 근데 여기에 조심할게 있다. 내가 못해서 그런지는 모르겠는데, NSFileManager의 copy… 메소드와 NSWorkspace의 performOperation을 이용해서는 도저히 카피가 되지를 않는다. 아무리 Authorization을 미리해도, 되지를 않는것이다.
Apple이 이 함수들의 설명에서 권한 문제에 대해서 언급을 하면 참 좋을텐데.

근데 오늘 Cocoa mailing list에서 답변을 얻었다. Factored program 모델에서 사용하는 식으로 AuthorizationExecuteWithPrivileges()를 이용해서 Unix command인 cp를 호출하면 되는 것이다. 근데 재미난 것이, 이땐 pre-authorization을 하지 않아도 되고, cp 자체가 authorization을 하지 않는 것으로 알고 있다. 분명 Factored approach에선 호출하는 프로세스에서 pre-authorization을 하고, 호출되는 프로세스에서 authorization을 하라고 되어 있는데도 말이지….

아무튼 되는 것을 포스팅해보자.

SFAuthorization *authorization = [SFAuthorization authorization];
AuthorizationFlags myFlags = kAuthorizationFlagDefaults |
							 kAuthorizationFlagInteractionAllowed | 
							 kAuthorizationFlagExtendRights; //| kAuthorizationFlagPreAuthorize; // Don't need Pre-Authorization.

NSError *authErr;
NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];

NSString *authorizationRightName = [[NSString alloc] initWithFormat:@"%@.Copy", [thisBundle bundleIdentifier]];
BOOL result = [authorization obtainWithRight:[authorizationRightName UTF8String]
									   flags:myFlags error:&authErr];

//	BOOL isSuccessful;
//	isSuccessful = [[NSFileManager defaultManager] copyPath:sourceFile toPath:PlugInPath handler:nil];
char *myArguments[] = { NULL, NULL, NULL };
myArguments[0] = (char *)[[theURL path] UTF8String];
myArguments[1] = (char *)[destFilePath UTF8String];

//OSStatus myStatus = AuthorizationExecuteWithPrivileges(mAuthorizationRef, "/bin/cp", kAuthorizationFlagDefaults, myArguments, NULL);
OSStatus myStatus = AuthorizationExecuteWithPrivileges([authorization authorizationRef], "/bin/cp", kAuthorizationFlagDefaults, myArguments

Apple의 BetterAuthorization이란 샘플코드가 Apple이 미는 방식으로 제대로 권한을 올리고 할 수있다고 한다. 근데.. 바빠 죽겠는데 그거 분석하고 이해해서 코딩할 시간이..
대충 보면 set뭐시기를 이용해서 프로그램 자체의 권한을 변경시켜버리는 것을 하지 말라는 것인거 같은데…

이 authorization쪽 문서가 많이 약하다. Apple에서 좀더 신경을 써 주면 좋겠다.

8 responses to this post.

  1. Posted by 이소스 되나요? on May 31, 2011 at 3:04 AM

    NSFileManager에서 /etc쪽으로 복사를 하려는데 안되서 이리저리 찾다가 여기까지 왔습니다.

    혹시 이 부분에 대해서 많이 아신다면 설명좀 부탁드려도 될까요?

    Reply

    • Posted by jongampark on May 31, 2011 at 6:27 PM

      소스 보시고, reference 보시면 아실텐데요?

      Reply

      • Posted by 이소스 되나요? on May 31, 2011 at 8:32 PM

        Undefined symbols for architecture x86_64:
        “_AuthorizationExecuteWithPrivileges”, referenced from:
        -[SayHostController startHost:] in SayHostController.o
        “_OBJC_CLASS_$_SFAuthorization”, referenced from:
        objc-class-ref in SayHostController.o
        ld: symbol(s) not found for architecture x86_64
        clang: error: linker command failed with exit code 1 (use -v to see invocation)

        에러가 x86_64에는 정의 되지 않았다고 하는데.. 이 부분 해결책을 잘 모르겠어서요.

        Reply

        • Posted by jongampark on May 31, 2011 at 8:59 PM

          잘 됩니다만?

          Reply

          • Posted by 이소스 되나요? on May 31, 2011 at 9:03 PM

            님이 잘된다면 할말 없죠. 근데 대답하는게 참 멋지시네요 잘 몰라서 질문한 사람한테 이딴식으로 댓글 다시는거 참 좋아 보입니다.

            Reply

            • Posted by jongampark on May 31, 2011 at 9:07 PM

              전화 번호가 어떻게 되십니까?

              Reply

            • Posted by jongampark on May 31, 2011 at 10:02 PM

              공허하군..

              Reply

            • Posted by jongampark on June 1, 2011 at 8:45 AM

              누구신지 모르겠으나, 이런게 예의인가 싶습니다.
              밑도 끝도 없이 설명 부탁한다 했는데, 도대체 어디서부터 어떤 것을 모르는 것인지, 제가 알 도리가 있습니까? 그래서 레퍼런스를 보라고 한 것입니다. 또한 그 후의 질문에서 64비트에서 해당 심볼을 못 찾는 것인데, 64비트의 경우를 꼭 집어서 물어봐서, “32비트에선 되나본데 64비트에선 안되는 것”인지 아니면 애초에 64비트로만 해봤는데 안된다는 것인지 알 도리가 있습니까? 더군다나 저는 일하고 있는 중이었습니다. 그 와중에 맥으로 부팅해서 테스트해보고, 이상한게 전혀 없어서, 저런 프로그래밍을 하실 정도면 링크하는 것이나 헤더 파일 체크, 프레임 워크 설정 등은 하실 줄 아는 분이라 생각되어, 더 이상 무엇을 설명해야 할지 몰라, (특별히 세팅할 것도 없고), “잘 되는 데요?”라고 답변을 쓴 것입니다. 거기다 대고 저런 댓글을 달다니요? 혹 학생입니까? 대개 어린 친구들이(나이만을 말하는게 아닙니다) 자기가 찾아보려고 하지 않고, 혹은 제대로 질문하지 않고, 상대가 답을 못 주면 욕을 하거나 “일부러 안가르쳐 주려고 해”하고 생각하는 경우가 많더군요.

              참 기분 나쁩니다. 제가 언제 답을 해도 상관없는 것을 퇴근하고, 거의 바로 답장을 쓴 것입니다. 제가 당신을 위해서 상시 대기해야 합니까? 덕분에 어제 집에서 일을 못했습니다. 기분 나뻐서.

              이 메시지를 볼까 모르겠지만, 참 경우가 없는 사람이군요.

              Reply

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: