locked
Problem with s4u logon impersonation - It does not impersonate and logs in with anonymous user RRS feed

  • 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 _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 process

    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 process

    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);

    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