Answered by:
Problem with s4u logon impersonation - It does not impersonate and logs in with anonymous user

Question
-
User1367049251 posted
Hi
We have requirements to do s4u login and get an impersonation token for the user who is authenticated by our own module (for external users).
We have written both a COM component as well as ISAPI extension. Here is the main code. Can you please tell why this is not impersonating?
Service account has Set TCB as privileges
ISAPI code
HANDLE getImpersonationToken2(char* inuserPrincipalName)
{
LogErrorEvent(L"Quintiles Extension doing a network logon", false);;
//Unit test code for network login
CLSID clsid;
HRESULT hr = CLSIDFromProgID(OLESTR("QuintilesImpersonator.QImpersonationCOM"), &clsid);
LogErrorEvent(L"Quintiles Extension got the COM class id",false);IQImpersonationCOM *prtIQImpersonationCOM = NULL;
//create the com
hr = CoCreateInstance(clsid, NULL,
CLSCTX_LOCAL_SERVER,IID_IQImpersonationCOM,
(LPVOID*) &prtIQImpersonationCOM);
LogErrorEvent(L"Quintiles Extension done the cocreate instance",false);
LPVOID testout = NULL;
if (SUCCEEDED(hr))
{
//finally... call the COM function via the interface pointer
LogErrorEvent(L"Quintiles Extension started to get a token",false);
_bstr_t userName(inuserPrincipalName);
if (NULL != prtIQImpersonationCOM)
{
prtIQImpersonationCOM->impersonateUser2((LONGLONG)GetCurrentProcessId(),userName,(LONGLONG*)&testout);
}
LogErrorEvent(L"Quintiles Extension finished getting a token", false);
prtIQImpersonationCOM->Release();
}
else
{
LogErrorEvent(L"Quintiles COM object could not be created", false);;
return NULL;
}
LogErrorEvent(L"Quintiles Extension doing a network logon completed", false);;
return testout;
}BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
//
// Tell IIS which version of ISAPI this extension was build from.
//pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR,
HSE_VERSION_MAJOR);//
// Report the description string for this extension. Ensure
// that it does not exceed the maximum length and is NULL
// terminated.
//strncpy( pVer->lpszExtensionDesc,
"Quintiles ISAPI extension ",
HSE_MAX_EXT_DLL_NAME_LEN );pVer->lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN-1] = '\0';
//
// Return TRUE if we successfully initialized.
//return TRUE;
}DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pecb)
{
HSE_EXEC_URL_INFO ExecUrlInfo;
HSE_EXEC_URL_USER_INFO ExecUrlUserInfo;
//HSE_EXEC_URL_ENTITY_INFO EntityInfo;
ISAPI_BUFFER * pbuffEntity = NULL;
ISAPI_REQUEST Request( pecb );
BOOL fModifiedEntity = FALSE;char* _username = "test5user@INET.QUINTILES.COM";
if ( pecb->cbTotalBytes == 0 )
{
LogErrorEvent(L"First call ExecURL", false);
goto CallExecUrl;
}
CallExecUrl://
// Use EXEC_URL to pass the request along
//
// We will pass NULL for all of the parts of the request
// that we don't want to modify.
//
// We will also use the HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR
// flag. This will ensure that UpCaseMap is not called again
// on this request (which could otherwise happen in some cases).
//
Request.ImpersonateClient();
LogErrorEvent(L"Before constructing user info in URL", false);
HANDLE _tempToken = NULL;
_tempToken=getImpersonationToken2(_username);ExecUrlUserInfo.pszCustomUserName = "Quintiles User";
ExecUrlUserInfo.pszCustomAuthType = "Quintiles Authentication";
ExecUrlUserInfo.hImpersonationToken= _tempToken;
ExecUrlInfo.pszUrl = NULL;
ExecUrlInfo.pszMethod = NULL;
ExecUrlInfo.pszChildHeaders = NULL;
ExecUrlInfo.pUserInfo = &ExecUrlUserInfo;
ExecUrlInfo.pEntity = NULL;
ExecUrlInfo.dwExecUrlFlags = HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR;
LogErrorEvent(L"After populating Exec url info", false);
if ( fModifiedEntity )
{
//ExecUrlInfo.pEntity = &EntityInfo;
}//
// Associate the completion routine and the current URL with
// this request.
//if ( pecb->ServerSupportFunction( pecb->ConnID,
HSE_REQ_IO_COMPLETION,
HandleCompletion,
NULL,
(DWORD*)ExecUrlUserInfo.hImpersonationToken) == FALSE )
{
LogErrorEvent(L"HSE_REQ_IO_COMPLETION FAILED", false);
goto Failed;
}
LogErrorEvent(L"HSE_REQ_IO_COMPLETION", false);
//
// Call ExecUrl
//if ( pecb->ServerSupportFunction( pecb->ConnID,
HSE_REQ_EXEC_URL,
&ExecUrlInfo,
NULL,
NULL ) == FALSE )
{
goto Failed;
}
LogErrorEvent(L"HSE_REQ_EXEC_URL", false);//
// Since EXEC_URL is asynchonous, we need to return STATUS_PENDING.
// The I/O completion routine will clean up.
//
LogErrorEvent(L"HSE_STATUS_PENDING",false);
return HSE_STATUS_PENDING;Failed:
//
// If we've successfully allocated our own entity buffer,
// delete it now.
//if ( pbuffEntity )
{
delete pbuffEntity;
pbuffEntity = NULL;
}//
// Send a 500 error
//
LogErrorEvent(L"SyncSendGenericServerError",true);
return SyncSendGenericServerError( pecb );
}
VOID WINAPI HandleCompletion(
EXTENSION_CONTROL_BLOCK * pecb,
VOID * pContext,
DWORD cbIO,
DWORD dwError
)
{
LogErrorEvent(L"Handle Completion entered ",false);HSE_EXEC_URL_STATUS ExecUrlStatus;
HANDLE hToken = (HANDLE)pContext;//
// The child is done. Delete the entity buffer now.
//if ( hToken )
{
CloseHandle( hToken );
hToken = NULL;
}//
// Get the child's HTTP status and set it into the ECB
//if ( pecb->ServerSupportFunction( pecb->ConnID,
HSE_REQ_GET_EXEC_URL_STATUS,
&ExecUrlStatus,
NULL,
NULL ) == TRUE )
{
pecb->dwHttpStatusCode = ExecUrlStatus.uHttpStatusCode;
}//
// Let IIS know that we are done with the
// ECB and return.
//pecb->ServerSupportFunction( pecb->ConnID,
HSE_REQ_DONE_WITH_SESSION,
NULL,
NULL,
NULL );
LogErrorEvent(L"Finished HSE_REQ_DONE_WITH_SESSION",false);
}STDMETHODIMP CQImpersonationCOM::impersonateUser2(LONGLONG sourceProcessID, BSTR userPrincipalName, LONGLONG* tokenHandle)
{
this->LogErrorEvent(L"Check Point 0 Impersonate user started", false);wchar_t *_inPrincipalName = NULL;_inPrincipalName = userPrincipalName;
HANDLE targetHandle;
this->LogErrorEvent(L"Form the duplicate handle impersonateUser2", false);this->LogErrorEvent(L"Before Duplicate handle", false);HANDLE primaryToken;
DuplicateTokenEx(_hImpersonationToken,TOKEN_ALL_ACCESS,NULL,SecurityDelegation,TokenImpersonation,&primaryToken);
this->LogErrorEvent(L"After DuplicateEx token access rights set", false);DuplicateHandle(GetCurrentProcess(),primaryToken,(HANDLE)targetProcess,&targetHandle,0,
false,DUPLICATE_SAME_ACCESS); this->LogErrorEvent(L"After Duplicate handle to the target process", false);*tokenHandle = (LONGLONG)targetHandle;
this->LogErrorEvent(L"Check Point 10 Impersonate user completed", false);return S_OK;}
Thursday, May 13, 2010 4:28 AM
Answers
-
User1367049251 posted
HANDLE _hImpersonationToken = this->_s4uLogon(_inPrincipalName); this->LogErrorEvent(L"Get a handle to target process impersonateUser2", false); HANDLE targetProcess = OpenProcess(PROCESS_DUP_HANDLE, false, sourceProcessID); this->LogErrorEvent(L"Got a handle to target process impersonateUser2", false); //Get a duplicate handle to the parent processHANDLE targetHandle;
this->LogErrorEvent(L"Form the duplicate handle impersonateUser2", false);this->LogErrorEvent(L"Before Duplicate handle", false);HANDLE primaryToken;
DuplicateTokenEx(_hImpersonationToken,TOKEN_ALL_ACCESS,NULL,SecurityDelegation,TokenImpersonation,&primaryToken);
this->LogErrorEvent(L"After DuplicateEx token access rights set", false);DuplicateHandle(GetCurrentProcess(),primaryToken,(HANDLE)targetProcess,&targetHandle,0,
false,DUPLICATE_SAME_ACCESS); this->LogErrorEvent(L"After Duplicate handle to the target process", false);Only the above lines need review as I gto Keith Brown's sample working with C# component
- Marked as answer by Anonymous Tuesday, September 28, 2021 12:00 AM
Friday, May 14, 2010 9:46 AM