Re: GinaStub, userinit.exe and Exception (0xc0000142)

From: Mike Collins (mikec_at_kr8.co.uk)
Date: 03/23/04


Date: Tue, 23 Mar 2004 09:29:02 -0000


"Richard Ward" <richardw@delete-yellow-dogs.com> wrote in message
news:105lan4jhkc399e@corp.supernews.com...
> What does the SID look like that you're returning?
>

My code is pretty much a copy of the example that appeared in MSDN under the
replacement Gina (which you wrote - I think). I have my main Gina.dll which
exposes the various Wlx functions, these are then passed to on to a class
that I have defined that deals with the actual "nitty-gritty" i.e.

Gina.dll -> WlxLoggedOutSAS -> TMainStub::LogOnUser <- this has identical
parameters to WlxLoggedOutSAS.

My actual code for TMainStub::LogOnUser looks like this:

int TMainStub::LogOnUser(PVOID pWlxContext, DWORD dwSasType, PLUID
pAuthenticationId, PSID pLogonSid,
                         PDWORD pdwOptions, PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile)
{
   int iRtn = WLX_SAS_ACTION_NONE;
   try
   {
      EnterCriticalSection(&lpCritSect);
      // Just for test purposes....
      strAuthData.szUsername = "mikec";
      strAuthData.szDomain = "HADES";
      strAuthData.szPassword = "come-death";

      HANDLE hUser = NULL;
      TOKEN_STATISTICS strTokenStats;
      TOKEN_GROUPS *pGroups;

      if (LogonUser((LPTSTR)strAuthData.szUsername.c_str(),
                          (LPTSTR)strAuthData.szDomain.c_str(),
                          (LPTSTR)strAuthData.szPassword.c_str(),
                          LOGON32_LOGON_INTERACTIVE,
                          LOGON32_PROVIDER_DEFAULT,
                          &hUser))
      {
         // Test the token for validity, just to be safe
         if (hUser)
         {
             DWORD dwSize;
             GetTokenInformation(hUser,
                                      TokenStatistics,
                                      &strTokenStats,
                                      sizeof(strTokenStats),
                                      &dwSize);

             *pAuthenticationId = strTokenStats.AuthenticationId;
             pGroups = (_TOKEN_GROUPS*)LocalAlloc(LMEM_FIXED, 1024); //<-
might need to check casting
             if (pGroups)
             {
                GetTokenInformation(hUser,
                                         TokenGroups,
                                         pGroups,
                                         1024,
                                         &dwSize);

                if (dwSize > 1024)
                {
                   pGroups = (_TOKEN_GROUPS*)LocalReAlloc(pGroups,
LMEM_FIXED, dwSize);
                   GetTokenInformation(hUser,
                                            TokenGroups,
                                            pGroups,
                                            dwSize,
                                            &dwSize);
                }

                for (DWORD i=0; i<pGroups->GroupCount; ++i)
                {
                        if ((pGroups->Groups[i].Attributes &
SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
                        {
                           CopySid(GetLengthSid(pLogonSid), pLogonSid,
pGroups->Groups[i].Sid);
                           break;
                        }
                }
                LocalFree(pGroups);

                // It all looks good... Save the token to our structure for
future reference / access
                strAuthData.hUserToken = hUser;

                // Assign the token to the passed pointer...
                *phToken = hUser;

                // Pass back null profile and options.
                *pdwOptions = 0;
                *pProfile =NULL;

                // Pass back multiple provider information.
                pMprNotifyInfo->pszUserName =
(WideString)strAuthData.szUsername;
                pMprNotifyInfo->pszDomain =
(WideString)strAuthData.szDomain;
                pMprNotifyInfo->pszPassword =
(WideString)strAuthData.szPassword;
                pMprNotifyInfo->pszOldPassword = NULL;

                iRtn = WLX_SAS_ACTION_LOGON;
             }
             else
             {
                CloseHandle(hUser);
             }
         }
    }
   __finally
   {
      LeaveCriticalSection(&lpCritSect);
   }
   return iRtn;
}

- more or less your code! As for my WlxActiveUserShell ->
TMainStub::ActiveUserShell, it's taken mostly from the example of
implementing WlxActiveUserShell from MSDN website (I didn't use the example
that was given with the Gina replacement because I was getting rubbish
returned from GetProfileString and I couldn't see the purpose of the while
loop):

BOOL TMainStub::ActiveUserShell(PVOID pWlxContext, PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
                                PVOID pEnvironment)
{
   BOOL bRtn = 0;
   STARTUPINFO si;
   PROCESS_INFORMATION pi;

   // Setup STARTUPINFO to pass to CreateProcessAsUser.
   ZeroMemory(&si, sizeof(si));
   si.cb = sizeof(STARTUPINFO);
   si.lpReserved = NULL;
   si.lpTitle = "userinit";
   si.dwX = si.dwY = si.dwXSize = si.dwYSize = 0L;
   si.dwFlags = 0;
   si.wShowWindow = SW_SHOW;
   si.lpReserved2 = NULL;
   si.cbReserved2 = 0;
   si.lpDesktop = (LPSTR)pszDesktopName;

   AnsiString szUserInitApp = "C:\\Winnt\\System32\\userinit.exe";

   // Don't understand why this is necessary...
   ImpersonateLoggedOnUser(strAuthData.hUserToken);

   bRtn = CreateProcessAsUser(strAuthData.hUserToken,
                             (LPCTSTR)szUserInitApp.c_str(),
                             NULL,
                             NULL,
                             NULL,
                             FALSE,
                             CREATE_UNICODE_ENVIRONMENT,
                             pEnvironment,
                             NULL,
                             &si,
                             &pi);
   if (bRtn==0)
   {
      // just for testing, never seems to get called, CreateProcessAsUser
always returns OK...
      ShowMessage(SysErrorMessage(GetLastError()).c_str());
   }
   RevertToSelf();

   // Release the memory winlogon allocated for the environment.
   VirtualFree(pEnvironment, 0, MEM_RELEASE);
   return bRtn;
}

- as mentioned above this all seems to execute ok and CreateProcessAsUser
always returns Ok, it is only after this point that I get the (0xc0000142)
exception being thrown. Any ideas? Starting to get desperate :-)

Thanks in advance,

Mike C



Relevant Pages

  • Re: GinaStub, userinit.exe and Exception (0xc0000142)
    ... My code is pretty much a copy of the example that appeared in MSDN under the ... replacement Gina. ... BOOL TMainStub::ActiveUserShell(PVOID pWlxContext, PWSTR pszDesktopName, ... BOOL bRtn = 0; ...
    (microsoft.public.platformsdk.security)
  • Re: VB5 Runtime on Windows 7
    ... | I haven't posted in the newsgroup for some time since there is an MSDN ... Plus the Microsoft servers don't carry it any longer. ...
    (microsoft.public.vb.general.discussion)