windows - Fra en tjeneste startet som Local System Account, kør et program som en logget bruger

Indlæg af Hanne Mølgaard Plasc

Problem



tl/dr: Jeg søger en måde at køre et program som den bruger, der er logget ind fra en tjeneste, der startes som Local System Account.





Lang version:


Opfølgning fra: Få nuværende brugernavn fra et program startet som Lokal systemkonto


Mit program er startet fra en tjeneste, der kører som Local System Account.


Denne service startes ved opstartstid i Windows og giver grundlæggende funktionalitet til nogle hardware knapper, f.eks. viser et tastatur på skærmen. Mit program er også tildelt en af ​​knapperne, men det er kun tilgængeligt, når en faktisk bruger er logget ind.


Hvad det gør er at tage et billede ved hjælp af et hardware kamera og gemme det et eller andet sted på filsystemet, hvilket fungerer fint, men jeg kan ikke gemme billeder på en netværkssti, hvilket er forståeligt, fordi det kræver godkendelse.


Hvis programmet startes direkte som den logget bruger, er denne godkendelse tilgængelig, og lagring af filer på en netværkssti fungerer fint.


Er der nogen måde, hvordan jeg kan løse dette problem?


Min foretrukne løsning ville være at starte programmet som den bruger, der for øjeblikket er logget ind uden at gemme adgangskoden og brugernavnet et sted.


Arbejdsløsning fundet på et andet websted:
http://chabster.blogspot.com/2008/01/run-as-interactive-user-from-service.html[7]


stdafx.h:


#include <WtsApi32.h>
#pragma comment(lib, "WtsApi32.lib")

#include <Userenv.h>
#pragma comment(lib, "Userenv.lib")


RunAsInteractiveUser funktion:


BOOL bRet;
HRESULT hr;

HANDLE processToken = NULL;
TOKEN\_PRIVILEGES oldTokenPrivileges = { 0 };

HANDLE impersonationToken = NULL;
HANDLE userToken = NULL;

LPVOID pEnvironment = NULL;
PROCESS\_INFORMATION processInformation = { 0 };

\_\_try {
    bRet = OpenProcessToken(GetCurrentProcess(), 
       TOKEN\_ADJUST\_PRIVILEGES | TOKEN\_QUERY, &processToken);
    if (!bRet) {
        hr = GetLastError();
        return hr;
    }

    // This step might not be necessary because 
    // SeTcbPrivilege is enabled by default for Local System
    LUID luid;
    bRet = LookupPrivilegeValue(NULL, \_T("SeTcbPrivilege"), &luid);
    if (!bRet) {
        hr = GetLastError();
        return hr;
    }

    TOKEN\_PRIVILEGES adjTokenPrivileges = { 0 };
    adjTokenPrivileges.PrivilegeCount = 1;
    adjTokenPrivileges.Privileges[0].Luid = luid;
    adjTokenPrivileges.Privileges[0].Attributes = SE\_PRIVILEGE\_ENABLED;

    DWORD dwOldTPLen;
    bRet = AdjustTokenPrivileges(processToken, FALSE, 
       &adjTokenPrivileges, sizeof(TOKEN\_PRIVILEGES), 
       &oldTokenPrivileges, &dwOldTPLen);

    if (bRet) {
        hr = GetLastError();
        if (hr == ERROR\_SUCCESS);
        else if (hr == ERROR\_NOT\_ALL\_ASSIGNED) {
            // Enabled by default
        }
    }
    else {
        hr = GetLastError();
        return hr;
    }

    DWORD conSessId = WTSGetActiveConsoleSessionId();
    if (conSessId == 0xFFFFFFFF) {
        // There is no session attached to the console
        return ERROR\_SUCCESS;
    }

    bRet = WTSQueryUserToken(conSessId, &impersonationToken);
    if (!bRet) {
        hr = GetLastError();
        return hr;
    }

    bRet = DuplicateTokenEx(impersonationToken, MAXIMUM\_ALLOWED, NULL,
       SecurityIdentification, TokenPrimary, &userToken);
    if (!bRet) {
        hr = GetLastError();
        return hr;
    }

    STARTUPINFO si = { 0 };
    si.cb = sizeof(STARTUPINFO);
    si.lpDesktop = \_T("winsta0\default");

    bRet = CreateEnvironmentBlock(&pEnvironment, userToken, TRUE);
    if (!bRet) {
        hr = GetLastError();
        return hr;
    }

    bRet = CreateProcessAsUser(userToken, \_T("C:\Windows\notepad.exe"), 
       NULL, NULL, NULL, FALSE, CREATE\_UNICODE\_ENVIRONMENT, 
       pEnvironment, NULL, &si, &processInformation);

    if (!bRet) {
        hr = GetLastError();
        return hr;
    }
}
\_\_finally {
    if (processInformation.hThread) {
        CloseHandle(processInformation.hThread);
    }
    if (processInformation.hProcess) {
        CloseHandle(processInformation.hProcess);
    }
    if (pEnvironment) {
        bRet = DestroyEnvironmentBlock(pEnvironment);
    }
    if (userToken) {
        CloseHandle(userToken);
    }
    if (impersonationToken) {
        CloseHandle(impersonationToken);
    }
    if (processToken) {
        bRet = AdjustTokenPrivileges(processToken, 
           FALSE, &oldTokenPrivileges, sizeof(TOKEN\_PRIVILEGES), NULL, NULL);
        CloseHandle(processToken);
    }
}

Bedste reference


du skal bruge CreateProcessAsUser. En guide kan findes her og her. Håber det hjælper. [8] [9]