DCOM Authentication Fails to use Kerberos, Falls back to NTLM
- by Asa Yeamans
I have a webservice that is written in Classic ASP. In this web service it attempts to create a VirtualServer.Application object on another server via DCOM. This fails with Permission Denied. However I have another component instantiated in this same webservice on the same remote server, that is created without problems. This component is a custom-in house component.
The webservice is called from a standalone EXE program that calls it via WinHTTP. It has been verified that WinHTTP is authenticating with Kerberos to the webservice successfully. The user authenticated to the webservice is the Administrator user. The EXE to webservice authentication step is successful and with kerberos.
I have verified the DCOM permissions on the remote computer with DCOMCNFG. The default limits allow administrators both local and remote activation, both local and remote access, and both local and remote launch. The default component permissions allow the same. This has been verified. The individual component permissions for the working component are set to defaults. The individual component permissions for the VirtualServer.Application component are also set to defaults. Based upon these settings, the webservice should be able to instantiate and access the components on the remote computer.
Setting up a Wireshark trace while running both tests, one with the working component and one with the VirtualServer.Application component reveals an intresting behavior. When the webservice is instantiating the working, custom, component, I can see the request on the wire to the RPCSS endpoint mapper first perform the TCP connect sequence. Then I see it perform the bind request with the appropriate security package, in this case kerberos. After it obtains the endpoint for the working DCOM component, it connects to the DCOM endpoint authenticating again via Kerberos, and it successfully is able to instantiate and communicate.
On the failing VirtualServer.Application component, I again see the bind request with kerberos go to the RPCC endpoing mapper successfully. However, when it then attempts to connect to the endpoint in the Virtual Server process, it fails to connect because it only attempts to authenticate with NTLM, which ultimately fails, because the webservice does not have access to the credentials to perform the NTLM hash.
Why is it attempting to authenticate via NTLM?
Additional Information:
Both components run on the same server via DCOM
Both components run as Local System on the server
Both components are Win32 Service components
Both components have the exact same launch/access/activation DCOM permissions
Both Win32 Services are set to run as Local System
The permission denied is not a permissions issue as far as I can tell, it is an authentication issue. Permission is denied because NTLM authentication is used with a NULL username instead of Kerberos Delegation
Constrained delegation is setup on the server hosting the webservice.
The server hosting the webservice is allowed to delegate to rpcss/dcom-server-name
The server hosting the webservice is allowed to delegate to vssvc/dcom-server-name
The dcom server is allowed to delegate to rpcss/webservice-server
The SPN's registered on the dcom server include rpcss/dcom-server-name and vssvc/dcom-server-name as well as the HOST/dcom-server-name related SPNs
The SPN's registered on the webservice-server include rpcss/webservice-server and the HOST/webservice-server related SPNs
Anybody have any Ideas why the attempt to create a VirtualServer.Application object on a remote server is falling back to NTLM authentication causing it to fail and get permission denied?
Additional information:
When the following code is run in the context of the webservice, directly via a testing-only, just-developed COM component, it fails on the specified line with Access Denied.
COSERVERINFO csi;
csi.dwReserved1=0;
csi.pwszName=L"terahnee.rivin.net";
csi.pAuthInfo=NULL;
csi.dwReserved2=NULL;
hr=CoGetClassObject(CLSID_VirtualServer, CLSCTX_ALL, &csi, IID_IClassFactory, (void **) &pClsFact);
if(FAILED( hr )) goto error1;
// Fails here with HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)
hr=pClsFact->CreateInstance(NULL, IID_IUnknown, (void **) &pUnk);
if(FAILED( hr )) goto error2;
Ive also noticed that in the Wireshark Traces, i see the attempt to connect to the service process component only requests NTLMSSP authentication, it doesnt even attmept to use kerberos. This suggests that for some reason the webservice thinks it cant use kerberos...