Доброго времени суток!
Для кастомизации своей гины использовал пример 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;
}