locked
Load user profile problem GINA RRS feed

  • Question

  • Im building a custom GINA DLL in which Im facing problems in loading the user profile when the user logs in... Im calling LsaLogonUser which returns among other parameters a profile buffer. The profile buffer is of type MSV1_0_INTERACTIVE_PROFILE. Th problem is all members of the profile buffer returned except the LogonServer are being returned null. Thus even if LsaLogonUser is working Im unable to shsow the user desktop. After successfull login it is simply restarting... Im including the appropriate code in th post ... plz help...

    int WINAPI WlxLoggedOutSAS(PVOID pWlxContext,DWORD dwSasType,PLUID pAuthenticationId,\
           PSID pLogonSid,PDWORD pdwOptions,PHANDLE phToken,\
           PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,PVOID *ppWinLogonProfile)
    {
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"ENTRY TO WlxLoggedOutSAS()");
     
     ZeroMemory(pNprNotifyInfo, sizeof *pNprNotifyInfo);

        *pdwOptions = 0; // we always let WinLogon load the user profile for us

        wchar_t*  profilePath = 0;

        int iRet = WLX_SAS_ACTION_NONE;

        if (WLX_SAS_TYPE_CTRL_ALT_DEL == dwSasType) {

      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"WLX_SAS_TYPE_CTRL_ALT_DEL Occured");
      

      //*******************UNCOMMENT THIS SECTION TO SHOW DIALOG USING DIALOGBOXINDIRECT***************
      
      HRSRC resource=FindResource(handleToCurrentModule,"#102",RT_DIALOG);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"FindResource Succeeded");

      HGLOBAL lpTemplate=LoadResource(handleToCurrentModule,resource);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"LoadResource Succeeded");

      iRet=DialogBoxIndirect(handleToCurrentModule,(LPCDLGTEMPLATE)lpTemplate,0,(DLGPROC)DialogProc);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"DialogBoxIndirect Succeeded");

      if(iRet != IDOK ) return iRet;
      
      //Form here we try to login by calling LsaLogonUser
      HANDLE lsaHandle;

      //Code to call LsaRegisterLogonProcess.......
      LSA_OPERATIONAL_MODE securityModeDummy;
      NTSTATUS returnCodeFromLsaFunctions;

      LSA_STRING lsaString;
      lsaString.Buffer = "MyLogon Process";
      lsaString.Length = strlen(lsaString.Buffer);
      lsaString.MaximumLength = lsaString.Length + 1;

      returnCodeFromLsaFunctions = LsaRegisterLogonProcess( &lsaString, &lsaHandle, &securityModeDummy);

      //If LsaRegisterLogonProcess is success proceed
      if(returnCodeFromLsaFunctions != STATUS_SUCCESS) {

       ULONG winErrorCode = LsaNtStatusToWinError(returnCodeFromLsaFunctions);
       LPTSTR s;
       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, winErrorCode, 0, (LPTSTR)&s, 0, NULL);
       FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LsaRegisterLogonProcess Failed. The Error was: %s", s);
       return WLX_SAS_ACTION_NONE;
      }

      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LsaRegisterLogonProcess Success");

      // attempt the login
            DWORD win32Error;
            MSV1_0_INTERACTIVE_PROFILE* pProfile = 0;
            if (!CallLsaLogonUser(lsaHandle, dmn, username, password, Interactive, pAuthenticationId, phToken, &pProfile, &win32Error)) {

                return WLX_SAS_ACTION_NONE;
            }
            if (!ExtractProfilePath(&profilePath, pProfile)) {
                return WLX_SAS_ACTION_NONE;
            }

      LPWSTR ProfilePath; 
      GetUserProfilePath(username, dmn, &ProfilePath);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,")-----%ls-----(", ProfilePath);
      
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LogonScript-%ls",pProfile->LogonScript.Buffer);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"HomeDirectory-%ls",pProfile->HomeDirectory.Buffer);  
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"FullName-%ls",pProfile->FullName.Buffer);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"ProfilePath-%ls",pProfile->ProfilePath.Buffer);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"HomeDirectoryDrive-%ls",pProfile->HomeDirectoryDrive.Buffer);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LogonServer-%ls",pProfile->LogonServer.Buffer);//Except the last value im getting evrything else as null

            LsaFreeReturnBuffer(pProfile);


      // if we get this far, the login succeeded, but there are a few minor things that could still fail
      int action = WLX_SAS_ACTION_NONE;
      bool success = false;
      
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Extracting Profile Path Done. Now Allocating Profile.");
      // Assume that WinLogon provides a buffer large enough to hold a logon SID,
      // which is of fixed length. It'd be nice if WinLogon would tell us how big
      // its buffer actually was, but it appears this is assumed.
      if (GetLogonSid(*phToken, pLogonSid, LOGON_SID_SIZE)) {

       if (AllocWinLogonProfile((WLX_PROFILE_V1_0**)ppWinLogonProfile, profilePath)) {

        if (WLX_SAS_TYPE_AUTHENTICATED == dwSasType) {
         success = true;
         action = WLX_SAS_ACTION_LOGON;
        }
        else {
         // copy login information for network providers
         pNprNotifyInfo->pszUserName = _localAllocString(username);
         pNprNotifyInfo->pszDomain   = _localAllocString(dmn);
         pNprNotifyInfo->pszPassword = _localAllocString(password);

         if (pNprNotifyInfo->pszUserName &&
          pNprNotifyInfo->pszDomain   &&
          pNprNotifyInfo->pszPassword) {

          success = true;
          action = WLX_SAS_ACTION_LOGON;
         }
        }
       }
      }
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Allocating Profile Done.");
     }
     else {
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"Unknown SAS.. :(");
      return WLX_SAS_ACTION_NONE;
     }
      
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__,"EXIT TO WlxLoggedOutSAS()");

     return iRet;

    }


    bool CallLsaLogonUser(
        HANDLE hLsa,
        const wchar_t* domain,
        const wchar_t* user,
        const wchar_t* pass,
        SECURITY_LOGON_TYPE logonType,
        LUID* pLogonSessionId,
        HANDLE* phToken,
        MSV1_0_INTERACTIVE_PROFILE** ppProfile,
        DWORD* pWin32Error) {

        bool result      = false;
        DWORD win32Error = 0;
        *phToken         = 0;

        LUID ignoredLogonSessionId;

        // optional arguments
        if (ppProfile)        *ppProfile   = 0;
        if (pWin32Error)      *pWin32Error = 0;
        if (!pLogonSessionId) pLogonSessionId = &ignoredLogonSessionId;

        /*LSA_STRING logonProcessName            = { 0 };*/
        TOKEN_SOURCE sourceContext             = { 's', 'a', 'm', 'p', 'l', 'e' };
        MSV1_0_INTERACTIVE_PROFILE* pProfile = 0;
        ULONG cbProfile = 0;
        QUOTA_LIMITS quotaLimits;
        NTSTATUS substatus;
        DWORD cbLogonRequest;

     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"_allocLogonRequest(domain, user, pass, &cbLogonRequest).....");
        MSV1_0_INTERACTIVE_LOGON* pLogonRequest =
            _allocLogonRequest(domain, user, pass, &cbLogonRequest);
        if (!pLogonRequest) {
            win32Error = ERROR_NOT_ENOUGH_MEMORY;
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Going to Cleanup bcos pLogonRequest is null....");
            goto cleanup;  
        }

     /*FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"_newLsaString(&logonProcessName, LOGON_PROCESS_NAME).....");
        if (!_newLsaString(&logonProcessName, LOGON_PROCESS_NAME)) {
            win32Error = ERROR_NOT_ENOUGH_MEMORY;
            goto cleanup;
        }*/
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Initializing LSA_STRING logonProcessName.....");
     LSA_STRING logonProcessName;
     logonProcessName.Buffer = "MyLogon Process";
     logonProcessName.Length = strlen(logonProcessName.Buffer);
     logonProcessName.MaximumLength = logonProcessName.Length + 1;

        // LsaLogonUser - the function from ____
        NTSTATUS status = LsaLogonUser(
            hLsa,
            &logonProcessName,  // we use our logon process name for the "origin name"
            logonType,
            LOGON32_PROVIDER_DEFAULT, // we use MSV1_0 or Kerb, whichever is supported
            pLogonRequest,
            cbLogonRequest,
            0,                  // we do not add any group SIDs
            &sourceContext,
            (void**)&pProfile,  // caller must free this via LsaFreeReturnBuffer
            &cbProfile,
            pLogonSessionId,
            phToken,
            &quotaLimits,       // we ignore this, but must pass in anyway
            &substatus);
     
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LsaLogonUser Call Over");

        if (status) {
            win32Error = LsaNtStatusToWinError(status);

            if ((ERROR_ACCOUNT_RESTRICTION == win32Error && STATUS_PASSWORD_EXPIRED == substatus)) {
                win32Error = ERROR_PASSWORD_EXPIRED;
            }

            *phToken = 0;
            pProfile = 0;

            //LDB2(L"LsaLogonUser failed. Status = %d, substatus = 0x%08X", win32Error, substatus);
      char *s,*ss;
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, win32Error, 0, (LPTSTR)&s, 0, NULL);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,s);
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, LsaNtStatusToWinError(substatus), 0, (LPTSTR)&ss, 0, NULL);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,ss);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LsaLogonUser Failed. Status : %s Substatus: %s", s ,ss);
            goto cleanup;
        }

        if (ppProfile) {
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"pProfile initialized...");
            *ppProfile = (MSV1_0_INTERACTIVE_PROFILE*)pProfile;
            pProfile = 0;
        }
        result = true;

    cleanup:
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Starting Cleanup in LsaLogonUser");
       
     // if caller cares about the details, pass them on
     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Dealing with pWin32Error.....");
        if (pWin32Error) *pWin32Error = win32Error;

     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"pLogonRequest cleanup.....");
        if (pLogonRequest) {
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"SecureZeroMemory(pLogonRequest, cbLogonRequest).....");
            SecureZeroMemory(pLogonRequest, cbLogonRequest);
      FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ," delete pLogonRequest.....");
            LocalFree(pLogonRequest);// Line No : 225
        }

     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"LsaFreeReturnBuffer(pProfile).....");
        if (pProfile) LsaFreeReturnBuffer(pProfile);

     FrdTraceWrite(FRD_TraceInfo,__FUNCTION__ ,"Finished Cleanup in LsaLogonUser");

        return result;
    }

    • Moved by nobugz Wednesday, September 16, 2009 5:41 PM not a c++ programming question (From:Visual C++ General)
    Wednesday, September 16, 2009 3:28 PM