C ++ Windows - запуск процесса через службу от имени пользователя без прав администратора - PullRequest
0 голосов
/ 18 июня 2019

Мы реализовали службу Windows, которая работает как пользователь SYSTEM и имеет права администратора. Если нашим клиентом управляет пользователь с правами администратора, он может без проблем запускать процессы через службу от имени администратора. Служба олицетворяет пользователя и запускает процесс с правами администратора.

Но теперь нам нужно сделать то же самое для пользователя без прав администратора. Я не смог найти никакой документации.

Код, который мы используем:

Получаем текущий токен

MyHandle Impersonator::getCurrentProcessToken() const
{
    MyHandle currentProcessToken;
    const auto returnCode = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_ALL_ACCESS, currentProcessToken);
    if (returnCode == 0 || *currentProcessToken == nullptr)
        throw EXCEPTION_STATIC(Exceptions::Windows::Impersonation, "Could not get token of current process", ::GetLastError());

    return currentProcessToken;
}

Устанавливаем токен привилегии

void Impersonator::enableTcbPrivilege() const
{
    MyHandle currentProcessToken = getCurrentProcessToken();

    TOKEN_PRIVILEGES tokenPrivilege;
    tokenPrivilege.PrivilegeCount = 1;
    tokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if (!::LookupPrivilegeValueW(nullptr, SE_TCB_NAME, &tokenPrivilege.Privileges[0].Luid))
        throw EXCEPTION(Exceptions::Windows::Elevation, "Could not lookup TCB privilege UID", ::GetLastError());

    /* Documentation for AdjustTokenPrivileges() can be found in the internet archive:
     * https://web.archive.org/web/20161009182045/https://msdn.microsoft.com/en-us/library/aa375202(v=vs.85).aspx
     */
    if (!::AdjustTokenPrivileges(*currentProcessToken, FALSE, &tokenPrivilege, 0, nullptr, nullptr))
        throw EXCEPTION(Exceptions::Windows::Elevation, "Could not enable TCB privilege", ::GetLastError());
}

Мы получаем связанный токен:

MyHandle UserImpersonator::getLinkedToken(MyHandle token) const
{
    TOKEN_LINKED_TOKEN linkedTokenStruct;
    DWORD returnLength = 0;
    const auto returnCode = ::GetTokenInformation(*token, TokenLinkedToken, &linkedTokenStruct, sizeof(linkedTokenStruct), &returnLength);
    MyHandle linkedToken(linkedTokenStruct.LinkedToken);
    if (returnCode == 0)
        throw EXCEPTION(Exceptions::Windows::Elevation, QString("Could not get admin token for user - error: %1").arg(QString::number(::GetLastError())), ::GetLastError());
    return linkedToken;
}

::GetTokenInformation завершается с ERROR_NO_SUCH_LOGON_SESSION

Я хотел бы знать, возможно ли то, что мы пытаемся достичь, и документировано ли это где-нибудь. Или любой намек на наш код, который может что-то упустить или ошибиться.

...