通过 DCOM 调用方法时的权限和/或安全问题

问题描述

目前我们正在尝试从远程办公室PC上的本地计算机启动Word进程,并且该进程以正确的用户在远程办公室PC上启动,但问题是该进程无法访问网络此用户所属的域中的目录。对于我们的 PC 和远程办公室 PC 之间的通信,我们使用 DCOM 对象。我们的代码如下所示:

void testSetup(const OLECHAR* filename)
{
    // Call CoInitialize or CoInitializeEx
    CoInitialize(NULL);

    // Create an Instance of Word.Application on RemoteOfficePC with CoCreateInstanceEx
    COAUTHINFO ca = {0};
    ca.dwAuthnSvc = RPC_C_AUTHN_WINNT;
    ca.dwAuthzSvc = RPC_C_AUTHZ_NONE;
    ca.dwAuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
    ca.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
    COAUTHIDENTITY
    authIdentity{(USHORT*)L"username",8,(USHORT*)L"domain",(USHORT*)L"************",12,SEC_WINNT_AUTH_IDENTITY_UNICODE};
    ca.pAuthIdentityData = &authIdentity;
    COSERVERINFO serverInfo = {0};
    serverInfo.pwszName = (LPWSTR)L"RemoteOfficePC";
    serverInfo.pAuthInfo = &ca;
    serverInfo.dwReserved1 = 0;
    serverInfo.dwReserved2 = 0;
    MULTI_QI qi = {&IID_Idispatch,NULL,S_OK};
    CLSID clsId;
    CLSIDFromString(L"{000209FF-0000-0000-C000-000000000046}",&clsId); // CLSID from Word.Application
    CoCreateInstanceEx(clsId,CLSCTX_REMOTE_SERVER,&serverInfo,1,&qi);
    Idispatch* pID = (Idispatch*)qi.pItf;

    // Call CoSetProxyBlanket to set the authentication information
    // Also tried it without the following call but with the same result
    if (false)
        CoSetProxyBlanket(pID,RPC_C_AUTHN_WINNT,// RPC_C_AUTHN_xxx
                          RPC_C_AUTHZ_NONE,// RPC_C_AUTHZ_xxx
                          NULL,// Server principal name
                          RPC_C_AUTHN_LEVEL_PKT_PRIVACY,// RPC_C_AUTHN_LEVEL_xxx
                          RPC_C_IMP_LEVEL_IMPERSONATE,// RPC_C_IMP_LEVEL_xxx
                          &authIdentity,EOAC_NONE); // proxy capabilities


    // get Interface for Documents of Word.Application
    disPID dispId = 6; // Documents object (Word)
    VARIANT vResult;
    Variantinit(&vResult);
    disPParaMS dpnoArgs = {NULL,0};
    pID->Invoke(dispId,IID_NULL,LOCALE_USER_DEFAULT,disPATCH_PROPERTYGET,&dpnoArgs,&vResult,NULL);
    pID = vResult.pdispVal;

    // Call CoSetProxyBlanket to set the authentication information
    // Also tried it without the following call but with the same result
    if (false)
        CoSetProxyBlanket(pID,EOAC_NONE); // proxy capabilities

    // Call Documents.Open method of the above Documents-Object
    // Documents.Open FileName:=filename,ReadOnly:=True
    VARIANT vArgs[16];
    disPParaMS dParams = {nullptr,nullptr,0};

    for (int i = 0; i < 16; ++i)
    {
        Variantinit(&vArgs[i]);
    }
    vArgs[0].vt = VT_BOOL;
    vArgs[2].vt = VT_BSTR;
    vArgs[0].boolVal = VARIANT_TRUE;
    vArgs[2].bstrVal = SysAllocString(filename);

    dParams.cArgs = 3;
    dParams.cNamedArgs = 0;
    dParams.rgvarg = vArgs;

    dispId = 19; // Documents.Open method (Word)
    EXCEPINFO exInfo;
    unsigned int mIndex;
    VARIANT result;

    pID->Invoke(dispId,disPATCH_METHOD,&dParams,&result,&exInfo,&mIndex);

    // result.pdispVal should be a Document object
    trAssertNotNull(result.pdispVal);
}

我们的测试如下:

//passes
void openLocalFile() { testSetup(L"C:\\temp\\Test.docx"); }

//passes
void openRemoteFile() { testSetup(L"\\\\RemoteOfficePC\\temp\\Test.docx"); }

//fails
void openFileFromDifferentDomain()
{
    // same domain to which the specified user belongs
    testSetup(L"\\\\externalFolder\\Test.docx");
}

请注意,指定用户在“Microsoft Word 97-2003-Document”组件的 DCOM 配置中拥有所有启动和激活权限、所有访问权限和所有配置权限。 此外,指定用户手动登录Remote-Office-PC后可以访问外部文件

如果我们使用 Remote-Office-PC 的本地路径或指向 Remote-Office-PC 本地文件的网络路径,我们会在 result 中找到一个 Document 对象。 如果我们使用指向该用户所属域中某个位置的路径,result 为空。

我们应该换个称呼吗? 我们错过了什么吗? 哪些安全设置可能会干扰我们尝试执行的操作?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)