I'm trying achieve two things with DCOM (Out of process)
My thoughts:
AFAIK the auth info structure contains the default authentication information (like username and password for RPC_C_AUTHN_WINNT) for all new COM calls. So instead of the process token the information in the auth structure should be used by COM. However, all COM calls/connections are always using the process' identity instead of the applied default one.
Usually, one can use CoSetProxyBlanket to change the auth info for a proxy. This works for me. My question here is whether it must or must not work if I impersonate the token myself and call the COM function. I've read in various MSDN articles that applying EOAC_DYNAMIC_CLOAKING to CoInitializeSecurity should make it working. However, my manually "impersonated COM calls always shows the process identity on the server side.
The client looks like this (Delphi)
var authList : SOLE_AUTHENTICATION_LIST; authidentity : SEC_WINNT_AUTH_IDENTITY_W; authInfo : array[0..1] of SOLE_AUTHENTICATION_INFO; pcAuthSvc : DWORD; asAuthSvc : array[0..0] of SOLE_AUTHENTICATION_SERVICE; Token : TJwSecurityToken; begin ZeroMemory( @authidentity, sizeof(authidentity) ); authidentity.User := 'Testbenutzer'; authidentity.UserLength := Length('Testbenutzer'); authidentity.Domain := ''; authidentity.DomainLength := 0; authidentity.Password := 'test'; authidentity.PasswordLength := 4; authidentity.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE; ZeroMemory( @authInfo, sizeof( authInfo ) ); // NTLM Settings authInfo[0].dwAuthnSvc := RPC_C_AUTHN_WINNT; authInfo[0].dwAuthzSvc := RPC_C_AUTHZ_NONE; authInfo[0].pAuthInfo := @authidentity; authList.cAuthInfo := 1; authList.aAuthInfo := @authInfo; OleCheck(CoInitializeSecurity( NULL, // Security descriptor -1, // Count of entries in asAuthSvc NULL, // asAuthSvc array NULL, // Reserved for future use RPC_C_AUTHN_LEVEL_CONNECT, // Authentication level RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation level @authList, // Authentication Information DWORd(EOAC_DYNAMIC_CLOAKING), // Additional capabilities NULL // Reserved )); //create COM object int := CoSecurityTestObj.Create; int.TestCall;
The server also has set the flag EOAC_DYNAMIC_CLOAKING. It uses CoImpersonateClient to get the thread token and the username. It also uses CoQueryClientBlanket to get the authInfo (as SEC_WINNT_AUTH_IDENTITY_W structure). However both calls always return the process identity of the client.
Also impersonating manually doesn't work (2.):
Token := TJwSecurityToken.CreateLogonUser(authidentity.User, '', authidentity.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT); Token.ImpersonateLoggedOnUser; int := CoSecurityTestObj.Create; int.TestCall;
Questions again:
Am I wrong or why is the default auth info structure (WinNT with username and password) not used as default authentication in each COM connection/call ?
Am I wrong or why doesn't manual impersonation work? Be aware that I tested number 2. separately so number 1. cannot interfere.
This is basic work for the JEDI Windows Security Code Library which I extend to support COM security. So your help will go GPL/MPL.
References:
Cloaking:
CoInitializeSecurity and pAuthInfo
Getting security blanket (server side)
Have you tried calling CoInitializeSecurity() with RPC_C_AUTHN_LEVEL_CALL instead of RPC_C_AUTHN_LEVEL_CONNECT?
Usually when I create DCOM clients I create COSERVERINFO and pass to CoCreateInstanceEx() with security credentials, remembering to call CoSetProxyBlanket() on all interfaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With