кастомизация MSGina.dll
От: Хацкевич Андрей Валентинович Россия  
Дата: 01.11.07 13:34
Оценка:
Доброго времени суток!

Для кастомизации своей гины использовал пример ginafull (http://www.microsoft.com/Rus/Download.aspx?file=/Msdn/Magazine/2005-06/SecurityBriefs0506.exe). Проблема заключается в том, что при входе в домен не подсоединяются сетевые диски. Я нашел топик на rsdn.ru на эту тему (http://rsdn.ru/Forum/Default.aspx?mid=2315464&flat=0), но полного решения там нет, а решить проблему с теми данными, которые там есть, у меня пока не получается.
Вопрос в следующем,- я инициализирую UserInitLogonServer, UserInitLogonScript в LoggedOutSAS и UserInitMprLogonScript в ActivateUserShell,- не ясно, где использовать эти переменные дальше..?
Буду очень признателен за помощь, особенно интересно мнение Lonely Dog в этом вопросе.
Ниже приведен фрагмент кода, который я и пытаюсь привести к нужному виду:

int Gina::LoggedOutSAS(DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions,
                       PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo, PVOID* ppWinLogonProfile) {

    ZeroMemory(pNprNotifyInfo, sizeof *pNprNotifyInfo);

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

    wchar_t*       profilePath = 0;
    const wchar_t* domain      = 0;
    const wchar_t* userName    = 0;
    const wchar_t* password    = 0;

    LogonDialog dlg(_pWinLogon);

    if (WLX_SAS_TYPE_CTRL_ALT_DEL == dwSasType) {

        // collect credentials from user
        if (IDOK != dlg.Show()) return WLX_SAS_ACTION_NONE;

        // attempt the login
        DWORD win32Error;
        MSV1_0_INTERACTIVE_PROFILE* pProfile = 0;
        if (!SecurityHelper::CallLsaLogonUser(_hLsa,
                                                dlg.domain, dlg.userName, dlg.password,
                                                Interactive,
                                                pAuthenticationId, phToken,
                                                &pProfile, &win32Error)) {
                
            // NOTE: a full implementation would deal with expired / must change passwords here
            // by reading the statistics in the profile and giving the user a chance to
            // change her password if it's expired or about to expire

            // message the user to let her know why the logon failed
            wchar_t msg[256];
            Log::LookupErrorMessage(msg, sizeof msg / sizeof *msg, win32Error);
            _pWinLogon->wlxMessageBox(0, msg, L"Logon Message", MB_ICONEXCLAMATION);
            return WLX_SAS_ACTION_NONE;
        }

        UNICODE_STRING    UserInitLogonServer=pProfile->LogonServer; 
    UNICODE_STRING    UserInitLogonScript=pProfile->LogonScript;

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

        //MessageBox(NULL, (LPCWSTR) pProfile->FullName, TEXT ("few"),NULL);
        LsaFreeReturnBuffer(pProfile);
        domain   = dlg.domain;
        userName = dlg.userName;
        password = dlg.password;

    }

    else if (WLX_SAS_TYPE_AUTHENTICATED == dwSasType) {
        // use the information in the other TS session to auto-logon this session
        WLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 credInfo;
        ZeroMemory(&credInfo, sizeof credInfo);
        credInfo.dwType = WLX_CONSOLESWITCHCREDENTIAL_TYPE_V1_0;

        LDB(L"Calling WlxQueryConsoleSwitchCredentials");

        if (_pWinLogon->wlxQueryConsoleSwitchCredentials(&credInfo)) {
            LDB(L"WlxQueryConsoleSwitchCredentials succeeded");
            *phToken    = credInfo.UserToken;
            profilePath = credInfo.ProfilePath;
            
            LDB1(L"Profile Path: [%d]", profilePath ? profilePath : L"<null>");

            if (!SecurityHelper::GetLogonSessionId(credInfo.UserToken, pAuthenticationId)) {
                // this should never fail, just a sanity check
                return WLX_SAS_ACTION_NONE;
            }

            // I believe the profile is already loaded in this case;
            // if you don't specify this option, WinLogon will fail and the error log will
            // complain that the profile failed to be loaded
            *pdwOptions = WLX_LOGON_OPT_NO_PROFILE;
        }
        else {
            LCF(L"WlxQueryConsoleSwitchCredentials failed");
            return WLX_SAS_ACTION_NONE;
        }
    }
    else {
        LDB1(L"WARNING: Unrecognized SAS type: %d", dwSasType);
        return WLX_SAS_ACTION_NONE;
    }

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

    // cache the profilePath in case we need to transfer it to another TS session
    LocalFree(_profilePath);
    _profilePath = profilePath;

    // 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 (SecurityHelper::GetLogonSid(*phToken, pLogonSid, LOGON_SID_SIZE)) {

        if (SecurityHelper::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(domain);
                pNprNotifyInfo->pszPassword = _localAllocString(password);

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

                    success = true;
                    action = WLX_SAS_ACTION_LOGON;
                }
            }
        }
    }

    if (success) {
        // GINA caches a copy of the interactive user's token
        _hToken = *phToken;
    }
    else {
        CloseHandle(*phToken);
        *phToken = 0;
    }
    return action;
}

BOOL Gina::ActivateUserShell(PWSTR pszDesktopName, PWSTR   pszMprLogonScript   , PVOID pEnvironment) {

    int programCount;
    wchar_t** programList;

    PWSTR UserInitMprLogonScript=pszMprLogonScript; 

    if (RegistryHelper::ReadUserInitProgramList(&programList, &programCount)) 
    {
        for (int i = 0; i < programCount; ++i) 
        {
            LDB1(L"programList[i] %s", programList[i]);
            LDB1(L"pszDesktopName %s", pszDesktopName);
            LCF1(L"hToken: %d", _hToken);
            LCF1(L"pEnvironment: %d", pEnvironment);

            if (!SecurityHelper::CreateProcessAsUserOnDesktop(_hToken, programList[i], pszDesktopName, pEnvironment))
            {
                break;
            }
        }
        RegistryHelper::FreeUserInitProgramList(programList, programCount);

        // GINA is required to release the environment block
        VirtualFree(pEnvironment, 0, MEM_RELEASE);
        LDB1(L"WARNING:  programCount: %d", programCount);
        return  programCount; // if we launched all the Userinit programs, we succeeded
    }
    return FALSE;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.