2012-06-11 3 views
0

현재 다른 시스템에서 실행중인 COM 개체에서 데이터를 검색해야하는 MFC 응용 프로그램을 작성 중입니다. 두 시스템에서 Windows XP를 실행하고 동일한 수동으로 설정된 사용자 계정 (즉, 두 시스템 모두에 동일한 사용자 이름과 암호, 도메인 없음)이 작동하는 경우 이미 동일한 데이터 교환 메커니즘이 작동하고 완벽하게 지원됩니다. 문제는 동일한 사용자 계정을 설정했지만 회사 도메인 사용자 계정으로 로그인 한 다른 컴퓨터에서이 동일한 DCOM 시스템에 액세스 할 수 있도록 설정하려고한다는 것입니다.COAUTHIDENTITY를 사용하여 CoCreateInstanceEx에서 다른 사용자를 제대로 가장 할 수 있습니까?

지금은 Run As를 사용하여 수동으로 응용 프로그램을 실행하고 대체 사용자를 지정하면 더 나은 솔루션을 찾고 있습니다. CoCreateInstanceEx에 COSERVERINFO에 대한 COAUTHIDENTITY를 설정할 때 대체 계정에 대한 사용자 이름과 암호를 지정 했으므로 작동하지 않는 것 같습니다. 도메인 항목에서 로컬 컴퓨터의 컴퓨터 이름, 원격 컴퓨터의 컴퓨터 이름, 공백으로 남겨 두었던 여러 가지 사항을 시도해 보았습니다.하지만 아무 것도 도움이되지 않습니다.

서버 컴퓨터의 개체에 대한 DCOM 사용 권한을 편집하여 Everyone 계정에 대한 전체 액세스를 허용했지만 도움이되지 않아서 무슨 일이 일어 났는지에 대한 의미있는 오류 메시지를 찾을 수 없었습니다. 정말 틀렸어. 서버 컴퓨터에서 일종의 로그 메시지를 받아서 실행 파일을 사용하여 실행할 때 정확한 자격 증명을 확인할 수 있다면 도움이 될 것입니다. 아무도 아이디어가 있니? 또는 도메인이 아닌 계정에서 DCOM 연결을 만들 때 시스템이 도메인에 사용하는 것을 알 수 있습니다. 컴퓨터 이름이 사용된다는 것을 암시하는 몇 가지 사항이 있지만 시도 할 때 작동하지 않습니다.

코드는 다음과 같습니다

COAUTHINFO  AuthInfo; 
COAUTHIDENTITY AuthIdentity; 
COSERVERINFO ServerInfo; 
MULTI_QI  Results;  

AuthIdentity.Domain    = (unsigned short *) w_domain; 
AuthIdentity.DomainLength  = wcslen(w_domain); 
AuthIdentity.Flags    = SEC_WINNT_AUTH_IDENTITY_UNICODE; 
AuthIdentity.Password   = (unsigned short *) w_password; 
AuthIdentity.PasswordLength  = wcslen(w_password); 
AuthIdentity.User    = (unsigned short *) w_username; 
AuthIdentity.UserLength   = wcslen(w_username); 

AuthInfo.dwAuthnLevel   = RPC_C_AUTHN_LEVEL_CALL; 
AuthInfo.dwAuthnSvc    = RPC_C_AUTHN_WINNT; 
AuthInfo.dwAuthzSvc    = RPC_C_AUTHZ_NONE; 
AuthInfo.dwCapabilities   = EOAC_NONE; 
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE; 
AuthInfo.pAuthIdentityData  = &AuthIdentity; 
AuthInfo.pwszServerPrincName = NULL; 

ServerInfo.dwReserved1 = 0; 
ServerInfo.dwReserved2 = 0; 
ServerInfo.pAuthInfo = &AuthInfo; 
ServerInfo.pwszName  = w_nodename; 

Results.pIID = &_uuidof(_DS_SessionContext); 
Results.pItf = NULL; 
Results.hr = 0; 

hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results);        
if(FAILED(hr)) 
{ 
    m_Error.Format("(0x%x) CoCreateInstanceEx for _DS_DataFrame failed.",hr); 
    m_Error2.Format("Make sure computer IP address is correct and connected."); 
    CoUninitialize(); 
    UpdateData(false); 
    UpdateWindow(); 
    return false;   
} 

pSession = (_DS_SessionContext *)Results.pItf; 

hr = pSession->raw_DS_GetVersion(&DSStatus, &version); 
if(FAILED(hr)) 
{ 
    m_Error.Format("(0x%x)GetVersion",hr); 
    CoUninitialize(); 
    UpdateData(false); 
    UpdateWindow(); 
    return false;   
} 

답변

0

아, 나는 그것을 알아 냈다. DCOM에서 인스턴스 및 호출 함수를 작성하면 동일한 보안 담요를 자동으로 사용하지 않는다는 것을 알 수 있습니다. CoCreateInstanceEx에 전달 된 COSERVERINFO의 인증 정보는 인스턴스 생성에만 적용되며 나중에 해당 인스턴스에서 함수를 호출하면 응용 프로그램의 자격 증명을 사용하여 해당 함수를 호출하기 때문에 실패합니다.

인스턴스에 함수를 호출하기 전에, 제대로하려면 내가 먼저 호출 (오류 처리는 명확성을 위해 생략)해야합니다

hr = CoSetProxyBlanket(Results.pItf, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, 
    RPC_C_IMP_LEVEL_IMPERSONATE, &AuthIdentity, EOAC_NONE); 

이 같은 일에 인스턴스를 호출하는 데 사용되는 보안 담요를 설정하는 그것을 만드는 데 사용되었고, 따라서 모든 것이 작동합니다.