him*_*elf 14 windows com remoting dcom
我有一个使用OLE自动化编组器的DCOM客户端和服务器应用程序.它们在同一台PC上运行时工作正常,但当服务器位于不在同一域的不同PC上时,我得到E_ACCESSDENIED(0x80070005).
服务器PC配置了dcomcnfg,以便为我在客户端上指定的登录名和密码的用户提供对任何DCOM对象的所有访问权限.ServerApp及其类型库已在服务器pc上注册.
类型库也在客户端PC上注册.我直接在ClientApp中指定服务器名称,因此据我所知,客户端PC上不需要dcomcnfg配置.
具有服务器名称,登录名,域名和密码的CreateInstanceEx()工作正常.它返回IUnknown,同时在服务器PC上启动ServerApp.
但是当我尝试使用QueryInterface()获取服务器支持的接口时,我得到了E_ACCESSDENIED.
分析安全事件日志,我有两条记录:
首先,我在ClientApp中指定其凭据的用户成功进行网络登录.当我调用CreateInstanceEx()时会发生这种情况.
接下来,我在客户端PC上登录的用户登录尝试失败.由于两台PC不在域中,因此服务器PC不知道该用户.
现在,为什么这个用户会登录到服务器,特别是当我调用所有东西的QueryInterface时?
研究CreateInterfaceEx参数,似乎有某种模仿机制正在进行中.但目前还不清楚是谁冒充了谁.涉及三个用户凭据:
ServerApp在服务器PC上运行的用户(在dcomcnfg中配置).
连接时ClientApp指定凭据的用户.
ClientApp在客户端PC上运行其凭据的用户.
无论你如何看待它,如果涉及#3,那么它就是一个用户.如果DCOM要在服务器PC上识别/模仿#3,为什么我需要指定#2的凭证?到了什么地步?
DCOM冒充#2似乎是合乎逻辑的,因为这是我明确指定为我的凭据.但为什么第二次登录尝试呢?
有人可以解释模仿是如何工作的,还有一种方法可以忽略它并以dcomcnfg中指定的用户身份运行?
him*_*elf 13
回答我自己的问题.经过大量探索后,很明显DCOM有两种不同的识别案例:
由于未知原因,#2不继承#1设置.默认情况下,它使用客户端进程的凭据,因此奇怪的登录.
有两种方法可以为#2指定凭据.第一个是CoSetProxyBlanket.它仅为指定代理(marshaller-unmarshaller)设置凭据:
CoCreateInstanceEx(IID_IObject1, /*login, pass*/, obj1); //Success!
//Logged in and recevied IObject1 proxy in obj1
obj1->DoSomething();
//IObject1 proxy in obj1 now tries to login under process credentials.
//Failure! E_ACCESSDENIED
CoSetProxyBlanket(obj1, /*login, pass*/); //Success!
//IObject1 proxy is now authorized.
obj1->DoSomething(); //Success!
obj1->QueryInterface(IID_IObject2, obj2); //Success!
obj2->DoSomethingElse(); //Failure!
//This different proxy for IObject2 have not yet been authorized.
CoSetProxyBlanket(obj2, /*login, pass*/);
//etc.
Run Code Online (Sandbox Code Playgroud)
重要的是要注意,虽然CoCreateInstanceEx要求模拟级别至少为IMPERSONATE,但CoSetProxyBlanket似乎不能处理除IDENTIFY之外的任何内容.
另一种选择是使用CoInitializeSecurity为整个过程设置默认凭据.然后你不必在每个代理上调用CoSetProxyBlanket:
CoInitializeSecurity(/* login, pass */);
CoCreateInstanceEx(IID_IUnknown, /*login, pass*/, obj); //Success!
obj->DoSomething(); //Success!
Run Code Online (Sandbox Code Playgroud)
在客户端上使用CoInitializeSecurity时,您也必须指定asAuthSvc,即使MSDN说您没有.
这种方法的缺点显然是,如果您有来自不同PC的多个DCOM对象,则必须在此调用中指定所有凭据,并且每次打开不同的代理时,可能会针对每台计算机尝试这些凭据.
当您从DLL运行时它也不可靠(如果进程具有不同的默认安全性,该怎么办?).因此,在每次调用返回之前,最好实现一个CoSetsProxyBlanket的QueryInterface包装器.
| 归档时间: |
|
| 查看次数: |
5545 次 |
| 最近记录: |