How do I run a COM service as System and allow any client from any security context to connect to it?
I have an .exe that hosts my class object by calling CoRegisterClassObject
. When I run the .exe as an Administrator, the same Administrator account can interact with it just fine. When I run the .exe as System, the Administrator account fails when calling CoCreateInstance
with error 0x80040154
.
UPDATE:
I've made some progress. In the COM service I register my class factory in the running object table with the ROTFLAGS_ALLOWANYCLIENT
flag. In the client I use the running object table's GetObject
method to get a pointer to the class factory. This allows me to access the service when it runs as an Administrator from a non-Administrator account. However, when it runs as System, a non-System client's CoCreateInstance
call fails with 0x80070005
. I suspect this issue is related to the one described here.
I was able to get it to work by doing the following in the COM service:
Calling CoInitializeSecurity in such a way to allow everyone to connect:
hresult = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IDENTIFY,
NULL,
0,
NULL);
Registering the class factory in the running object table, specifying ROTFLAGS_ALLOWANYCLIENT:
hresult = pIRunningObjectTable->Register(
ROTFLAGS_ALLOWANYCLIENT |ROTFLAGS_REGISTRATIONKEEPSALIVE,
pClassFactory,
pIMoniker,
&dwROTRegister);
And doing the following in the COM client:
Accessing the class factory from the running object table:
hresult = pIRunningObjectTable->GetObjectW(pIMoniker, &pIUnknown);
hresult = pIUnknown->QueryInterface(IID_IClassFactory, (PVOID *)&pIClassFactory);
I had to configure some registry settings to get it work correctly. Setting HKCR\AppID\<guid>\LocalService
prevented it from working, so I do not have it defined. I set HKCR\AppID\<guid>\RunAs
to NT Authority\System
.