LogonUser в Windows7/Server2008R2
От: xaxaTyH  
Дата: 09.01.11 16:19
Оценка:
Добрый день.

Есть задача: есть некое средство развертывания приложений, которое доставляет пакет на конечную машину и запускает его из-под учетки localsystem. В этом пакете(в коде) нужно залогиниться под учеткой сетевого админа и запустить на установку патч.

Пытаюсь залогиниться следующим образом:

#include <Windows.h>
#include <Userenv.h>
#include <tchar.h>
#include <string>

FILE *fp = NULL;

int main(int argc, TCHAR *argv[])
{
    HANDLE hToken;
    PROFILEINFO prInfo;

    DWORD dwSize;
    WCHAR szUserProfile[256] = L"";

    LPVOID lpvEnv;

    STARTUPINFO si_setup;
    PROCESS_INFORMATION pi_setup;

    //Кодировка по умолчанию
    _tsetlocale(LC_ALL, L"");

    //Создание и открытите файла лога
    _tfopen_s(&fp, L"C:\\Logon.log", L"w");

    if(!::LogonUser(L"user", L"domain", L"pass", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken))
    {
        _ftprintf(fp, L"LogonUser() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"LogonUser() successful!\n");
        _ftprintf(fp, L"LogonUser() SUCCESS with error code: %d\n", ::GetLastError());
    }

    ::ZeroMemory(&prInfo, sizeof(PROFILEINFO));
    prInfo.dwSize = sizeof(PROFILEINFO);
    prInfo.lpUserName = L"test";
    prInfo.dwFlags = PI_NOUI;

    if(!::LoadUserProfile(hToken, &prInfo))
    {
        _ftprintf(fp, L"LoadUserProfile() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"LoadUserProfile() successful!\n");
        _ftprintf(fp, L"LoadUserProfile() SUCCESS with error code: %d\n", ::GetLastError());
    }

    if(!::ImpersonateLoggedOnUser(hToken))
    {
        _ftprintf(fp, L"ImpersonateLoggedOnUser() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"ImpersonateLoggedOnUser() successful!\n");
        _ftprintf(fp, L"ImpersonateLoggedOnUser() SUCCESS with error code: %d\n", ::GetLastError());
    }

    dwSize = sizeof(szUserProfile)/sizeof(WCHAR);

    if(!::GetUserProfileDirectory(hToken, szUserProfile, &dwSize))
    {
        _ftprintf(fp, L"GetUserProfileDirectory() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"GetUserProfileDirectory() successful!\n");
        _ftprintf(fp, L"GetUserProfileDirectory() SUCCESS with error code: %d\n", ::GetLastError());
    }

    if(!::CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
    {
        _ftprintf(fp, L"CreateEnvironmentBlock() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"CreateEnvironmentBlock() successful!\n");
        _ftprintf(fp, L"CreateEnvironmentBlock() SUCCESS with error code: %d\n", ::GetLastError());
    }

    ::ZeroMemory(&si_setup, sizeof(STARTUPINFO));
    si_setup.cb = sizeof(STARTUPINFO);
    si_setup.lpDesktop = L"Winsta0\Default";
    ::ZeroMemory(&pi_setup, sizeof(PROCESS_INFORMATION));

    if(!::CreateProcessAsUser(hToken, L"Setup.exe", NULL, NULL, NULL, NULL, CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile, &si_setup, &pi_setup))
    {
        _ftprintf(fp, L"CreateProcessAsUser() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"CreateProcessAsUser() successful!\n");
        _ftprintf(fp, L"CreateProcessAsUser() SUCCESS with error code: %d\n", ::GetLastError());
    }


    if(!DestroyEnvironmentBlock(lpvEnv))
    {
        _ftprintf(fp, L"DestroyEnvironmentBlock() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"DestroyEnvironmentBlock() successful!\n");
        _ftprintf(fp, L"DestroyEnvironmentBlock() SUCCESS with error code: %d\n", ::GetLastError());
    }

    if(!::UnloadUserProfile(hToken, prInfo.hProfile))
    {
        _ftprintf(fp, L"UnloadUserProfile() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"UnloadUserProfile() successful!\n");
        _ftprintf(fp, L"UnloadUserProfile() SUCCESS with error code: %d\n", ::GetLastError());
    }

    fclose(fp);

    ::CloseHandle(hToken);
    ::CloseHandle(pi_setup.hProcess);
    ::CloseHandle(pi_setup.hThread);

    return 1;
}


Получаю ошибки:


Возможно, что-то не так в корне делаю. Буду признателен за помощь/советы.
Re: LogonUser в Windows7/Server2008R2
От: CreatorCray  
Дата: 09.01.11 19:42
Оценка:
Здравствуйте, xaxaTyH, Вы писали:

TH>Есть задача: есть некое средство развертывания приложений, которое доставляет пакет на конечную машину и запускает его из-под учетки localsystem. В этом пакете(в коде) нужно залогиниться под учеткой сетевого админа и запустить на установку патч.

TH>LoadUserProfile() SUCCESS with error code: 1008 == "An attempt was made to reference a token that does not exist."
На которой из виндов пробуешь то?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: LogonUser в Windows7/Server2008R2
От: xaxaTyH  
Дата: 09.01.11 20:27
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, xaxaTyH, Вы писали:


TH>>Есть задача: есть некое средство развертывания приложений, которое доставляет пакет на конечную машину и запускает его из-под учетки localsystem. В этом пакете(в коде) нужно залогиниться под учеткой сетевого админа и запустить на установку патч.

TH>>LoadUserProfile() SUCCESS with error code: 1008 == "An attempt was made to reference a token that does not exist."
CC>На которой из виндов пробуешь то?

На Windows 7 Professional x64. Также пробовал на Windows Server 2008 R2 x64.
Re[3]: LogonUser в Windows7/Server2008R2
От: Jolly Roger  
Дата: 10.01.11 03:12
Оценка:
Здравствуйте, xaxaTyH, Вы писали:

А Вы проверьте полученный токен на членство в группах (GetTokenInformation с TokenGroups).
"Нормальные герои всегда идут в обход!"
Re[4]: LogonUser в Windows7/Server2008R2
От: xaxaTyH  
Дата: 10.01.11 18:50
Оценка: :))
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, xaxaTyH, Вы писали:


JR>А Вы проверьте полученный токен на членство в группах (GetTokenInformation с TokenGroups).


Вывел группы и атрибуты токена таким образом:

/*Получение информации о группах токена*/
    DWORD dwTGSize = 0;
    PTOKEN_GROUPS lpTokenGroups;

    //Берем размер буфера
    ::GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS::TokenGroups, NULL, 0, &dwTGSize);

    //Выделяем память под буфер
    lpTokenGroups = (PTOKEN_GROUPS)::LocalAlloc(LPTR, dwTGSize);

    if(!::GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS::TokenGroups, lpTokenGroups, ::LocalSize(lpTokenGroups), &dwTGSize))
    {
        _tprintf_s(L"GetTokenInformation() FAILED with error code: %d\n", ::GetLastError());
        _ftprintf(fp, L"GetTokenInformation() FAILED with error code: %d\n", ::GetLastError());
        fclose(fp);
        ::CloseHandle(hToken);
        return 0;
    }
    else
    {
        _tprintf_s(L"GetTokenInformation() SUCCESS with error code: %d\n", ::GetLastError());
        _ftprintf(fp, L"GetTokenInformation() SUCCESS with error code: %d\n", ::GetLastError());
    }

    //Запись групп Token'a
    _tprintf_s(L"Token Groups for hToken:\n");

    for(int i = 0; i < lpTokenGroups->GroupCount; i++)
    {
        LPTSTR lptStringSid = NULL;

        if(!::ConvertSidToStringSid(lpTokenGroups->Groups->Sid, &lptStringSid))
        {
            _tprintf_s(L"ConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
            _ftprintf(fp, L"GConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
        }

        _tprintf_s(L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);
        _ftprintf(fp, L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);

        ::LocalFree(lptStringSid);
    }
        
    ::LocalFree(lpTokenGroups);
    /*Завершение получения информации о группах токена*/

Получил результат:

Не понял, почему 12 групп с одинаковым SID и что за значение SID — 7.. В Winnt.h такого значения не нашел.
Re[5]: LogonUser в Windows7/Server2008R2
От: CreatorCray  
Дата: 10.01.11 19:24
Оценка:
Здравствуйте, xaxaTyH, Вы писали:

TH> for(int i = 0; i < lpTokenGroups->GroupCount; i++)

TH> {
TH> LPTSTR lptStringSid = NULL;

TH> if(!::ConvertSidToStringSid(lpTokenGroups->Groups->Sid, &lptStringSid))

TH> {
TH> _tprintf_s(L"ConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
TH> _ftprintf(fp, L"GConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
TH> }

TH> _tprintf_s(L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);

TH> _ftprintf(fp, L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);

TH> ::LocalFree(lptStringSid);

TH> }

TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.

TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.

TH>Не понял, почему 12 групп с одинаковым SID и что за значение SID — 7.. В Winnt.h такого значения не нашел.


Скажи, а где ты переменную i используешь то?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[6]: LogonUser в Windows7/Server2008R2
От: xaxaTyH  
Дата: 10.01.11 20:14
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, xaxaTyH, Вы писали:


TH>> for(int i = 0; i < lpTokenGroups->GroupCount; i++)

TH>> {
TH>> LPTSTR lptStringSid = NULL;

TH>> if(!::ConvertSidToStringSid(lpTokenGroups->Groups->Sid, &lptStringSid))

TH>> {
TH>> _tprintf_s(L"ConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
TH>> _ftprintf(fp, L"GConvertSidToStringSid() FAILED with error code: %d\n", ::GetLastError());
TH>> }

TH>> _tprintf_s(L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);

TH>> _ftprintf(fp, L"Sid: %s. Attributes: %d.\n", lptStringSid, lpTokenGroups->Groups->Attributes);

TH>> ::LocalFree(lptStringSid);

TH>> }

TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.

TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.
TH>>Sid: S-1-5-21-2143115735-4289703453-2575764236-513. Attributes: 7.

TH>>Не понял, почему 12 групп с одинаковым SID и что за значение SID — 7.. В Winnt.h такого значения не нашел.

CC>
CC>Скажи, а где ты переменную i используешь то?

Косяк, не заметил

Re[7]: LogonUser в Windows7/Server2008R2
От: Jolly Roger  
Дата: 11.01.11 07:10
Оценка:
Здравствуйте, xaxaTyH, Вы писали:

С группами вроде нормально, осталось выяснить, для чего Вы вызываете ImpersonateLoggedOnUser. Возможно, после имперсонации текущий маркер потока не имеет доступа к маркеру, полученному до имперсонации, т.е. к самому себе. Попробуйте убрать вызов ImpersonateLoggedOnUser.
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.