Search code examples
winapicomdcom

Run a COM Service as System


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.


Solution

  • I was able to get it to work by doing the following in the COM service:

    1. 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);
      
    2. 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:

    1. 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.