CoInitializeSecurity: Impersonation level for code
hosted in a surrogate
Using C#, I have come across a similar problem and tried the following
---------------------------------------------------
static class Program
{
//**** Program Initialization ****
[System.Runtime.InteropServices.DllImport("ole32.dll")]
public static extern int CoInitializeSecurity(IntPtr pVoid, int
cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1, xmSam.Defs.RpcAuthnLevel level,
xmSam.Defs.RpcImpLevel impers, IntPtr pAuthList, xmSam.Defs.EoAuthnCap dwCapabilities, IntPtr
pReserved3);
[STAThread]
static void Main()
{
CSecurityManager SecurityManager = new CSecurityManager();
SecurityManager.Run();
long nHResult ;
nHResult = CoInitializeSecurity(IntPtr.Zero,
-1,
IntPtr.Zero,
IntPtr.Zero,
RpcAuthnLevel.None,
RpcImpLevel.Impersonate,
IntPtr.Zero,
EoAuthnCap.None,
IntPtr.Zero));
#if DEBUG
if (xmSam.Defs.S_OK != nHResult)
{
MessageBox.Show("Security failed to initialize");
}
else
{
MessageBox.Show("Security has been initialized successfully");
}
#endif
//******* the rest of my main function in Program.cs **********************
--------------------------------------------------- to overwrite the security level using my .Net application which calls my COM Object (DLL in VC++) but I failed but finally I managed to achieve the impersonation from within the COM itself. In other words,
My C# .Net application has already called CoInitializeSecurity during start up, and since
you can only call this API once during the life of a process, you won't be able to change any settings from your code.
So this is how I did it from my COM using CoSetProxyBlanket().
-----------------------------------------------------
bool MyClass::OverwiteSecurity()
{
try
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CComPtr< IWbemServices > pWbemServices ;
//IWbemServices*
CComPtr< IWbemLocator > locator;
HRESULT hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL,
CLSCTX_INPROC_SERVER, IID_IWbemLocator,
reinterpret_cast< void** >( &locator ) );
if ( FAILED( hr ) )
{
#ifdef _DEBUG
MessageBox(NULL, L"Failed to Obtain the initial locator to WMI" , L"MyDllName", MB_OK);
#else
return false;
#endif
}
//CComPtr< IWbemServices > service;
hr = locator->ConnectServer( L"root\\cimv2", NULL, NULL, NULL,
WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pWbemServices );
if ( FAILED( hr ) )
{
#ifdef _DEBUG
MessageBox(NULL, L"Failed to Connect to WMI through the IWbemLocator" , L"MyDllName", MB_OK);
#else
return false;
#endif
}
// Set proxy security for pWbemServices interface to RPC_C_IMP_LEVEL_IMPERSONATE
hr = CoSetProxyBlanket(pWbemServices,
RPC_C_AUTHN_DEFAULT,
RPC_C_AUTHZ_NONE,
COLE_DEFAULT_PRINCIPAL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
if (FAILED(hr))
{
#ifdef _DEBUG
wchar_t buf[100];
swprintf( buf, 100, L"%s: %u", L"Count not set proxy blanket1. Error code = ", hr );
MessageBox(NULL, L"Failed to ConnectServer" , L"MyDllName", MB_OK);
#else
return false;
#endif
}
// by now you have overwritten the security level
// and have full control through pWbemServices.
// For example the following piece of code access
// one of WMI database tables to determine whether // a device with a Name like "TECHLOG USB Serial
// Port" is plugged into your one of PC serial
// ports and if so it will retreive the full name of the device which include the COM port # as well.
CComPtr< IEnumWbemClassObject > enumerator;
hr = pWbemServices->ExecQuery( L"WQL", L"SELECT * FROM CIM_LogicalDevice where Name like 'TECHLOG USB Serial Port (COM%'",
WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator );
if ( SUCCEEDED( hr ) )
{
// read the first instance from the enumeration (only one Device)
CComPtr< IWbemClassObject > Device = NULL;
ULONG retcnt;
hr = enumerator->Next( WBEM_INFINITE, 1L, reinterpret_cast<IWbemClassObject**>( &Device ), &retcnt );
if ( SUCCEEDED( hr ) )
{
_variant_t var_val;
hr = Device->Get( L"Name", 0, &var_val, NULL, NULL );
if ( SUCCEEDED( hr ) )
{
strDeviceDetails = var_val;
}
else
{
#ifdef _DEBUG
MessageBox(NULL, L"Failed to retreive the Name of the Device" , L"MyDllName", MB_OK);
#else
return false;
#endif
}
}
}
else
{
#ifdef _DEBUG
MessageBox(NULL, L"ID_TECH Card Reder Device not found" , L"MyDllName", MB_OK);
#else
return false;
#endif
}
return true;
}
catch(...)
{
}
}
-----------------------------------------------------
Hope this answer may help.
EggHeadCafe - .NET Developer Portal of Choice
http://www.eggheadcafe.com/default.aspx?ref=ng