Exemplo n.º 1
0
static BOOL
AllowWinstaAccess(PWLSESSION Session)
{
    BOOL bSuccess = FALSE;
    DWORD dwIndex;
    DWORD dwLength = 0;
    PTOKEN_GROUPS ptg = NULL;
    PSID psid;
    TOKEN_STATISTICS Stats;
    DWORD cbStats;
    DWORD ret;

    // Get required buffer size and allocate the TOKEN_GROUPS buffer.

    if (!GetTokenInformation(Session->UserToken,
                             TokenGroups,
                             ptg,
                             0,
                             &dwLength))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            return FALSE;

        ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
        if (ptg == NULL)
            return FALSE;
    }

    // Get the token group information from the access token.
    if (!GetTokenInformation(Session->UserToken,
                             TokenGroups,
                             ptg,
                             dwLength,
                             &dwLength))
    {
        goto Cleanup;
    }

    // Loop through the groups to find the logon SID.

    for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
    {
        if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
            == SE_GROUP_LOGON_ID)
        {
            psid = ptg->Groups[dwIndex].Sid;
            break;
        }
    }

    dwLength = GetLengthSid(psid);

    if (!GetTokenInformation(Session->UserToken,
                             TokenStatistics,
                             &Stats,
                             sizeof(TOKEN_STATISTICS),
                             &cbStats))
    {
        WARN("Couldn't get Authentication id from user token!\n");
        goto Cleanup;
    }

    AddAceToWindowStation(Session->InteractiveWindowStation, psid);

    ret = SetWindowStationUser(Session->InteractiveWindowStation,
                               &Stats.AuthenticationId,
                               psid,
                               dwLength);
    TRACE("SetWindowStationUser returned 0x%x\n", ret);

    bSuccess = TRUE;

Cleanup:

    // Free the buffer for the token groups.
    if (ptg != NULL)
        HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

    return bSuccess;
}
Exemplo n.º 2
0
ActivePet::ActivePet(wchar_t* user_password,
                     std::wstring petname,
                     FileEventLoop* files) : m_petname(petname),
                                             m_files(files),
                                             m_session(INVALID_HANDLE_VALUE),
                                             m_profile(INVALID_HANDLE_VALUE),
                                             m_job(CreateJobObject(NULL, NULL)),
                                             m_next_editable_name(1),
                                             m_ticks_while_invisible(0)
{
    // Create a new logon session for the pet.
    std::wstring petRegistryPath = Constants::registryPets() + L"\\" + m_petname;
	RegKey petkey = RegKey::HKCU.open(petRegistryPath);
	std::wstring accountName = petkey.getValue(L"accountName");
    std::wstring accountRegistryPath = Constants::registryAccounts() + L"\\" + accountName;
	RegKey accountKey = RegKey::HKCU.open(accountRegistryPath);	
	std::wstring password = accountKey.getValue(L"password");
	if (!LogonUser(accountName.c_str(), NULL, password.c_str(),
				   LOGON32_LOGON_INTERACTIVE,
				   LOGON32_PROVIDER_DEFAULT,
				   &m_session)) {
        printf("LogonUser() failed: %d\n", GetLastError());
        return;
	}

    // Tweak the Winsta0 and desktop ACLs to allow the pet to create windows.
    auto_buffer<PSID> logon_sid = GetLogonSID(m_session.get());
    if (NULL == logon_sid.get()) {
        return;
    }
    auto_close<HWINSTA, &::CloseWindowStation> winsta0(OpenWindowStation(L"winsta0", FALSE, READ_CONTROL | WRITE_DAC));
	if (NULL == winsta0.get()) {
        printf("OpenWindowStation() failed: %d\n", GetLastError());
        return;
	}
	if (!AddAceToWindowStation(winsta0.get(), logon_sid.get())) {
        printf("AddAceToWindowStation() failed: %d", GetLastError());
		return;
	}
    auto_close<HDESK, &::CloseDesktop> desktop(OpenDesktop(L"default", 0, FALSE,
                                                           READ_CONTROL | WRITE_DAC |
                                                           DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS));
	if (NULL == desktop.get()) {
        printf("OpenDesktop() failed: %d\n", GetLastError());
		return;
	}
    if (!AddAceToDesktop(desktop.get(), logon_sid.get())) {
        printf("AddAceToDesktop() failed: %d\n", GetLastError());
		return;
	}

    // Load the pet account's registry hive.
    wchar_t account[128] = {};
    wcsncpy(account, accountName.c_str(), 128);
	PROFILEINFO profile = { sizeof(PROFILEINFO), 0, account };
	if (!LoadUserProfile(m_session.get(), &profile)) {
        printf("LoadUserProfile() failed: %d\n", GetLastError());
		return;
	}
    m_profile = profile.hProfile;

    // Initialize the pet job.
	if (NULL == m_job.get()) {
        printf("CreateJobObject() failed: %d\n", GetLastError());
		return;
	}
    JOBOBJECT_BASIC_UI_RESTRICTIONS buir = { JOB_OBJECT_UILIMIT_HANDLES };
	if (!SetInformationJobObject(m_job.get(), JobObjectBasicUIRestrictions, &buir, sizeof buir)) {
        printf("SetInformationJobObject() failed: %d\n", GetLastError());
	}

    // Some apps fail to launch without access to the desktop window.
	if (!UserHandleGrantAccess(GetDesktopWindow(), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}

    // Give apps access to all the standard cursors.
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ARROW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_IBEAM), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_WAIT), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_CROSS), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_UPARROW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_ICON), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENWSE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENESW), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEWE), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZENS), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_SIZEALL), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_NO), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HAND), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_APPSTARTING), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}
	if (!UserHandleGrantAccess(LoadCursor(NULL, IDC_HELP), m_job.get(), TRUE)) {
        printf("UserHandleGrantAccess() failed: %d\n", GetLastError());
	}

    // Setup the use records for the printers.
    std::set<std::wstring> servers;
    RegKey printers = RegKey::HKCU.open(L"Printers\\Connections");
    for (int i = 0; true; ++i) {
        RegKey printer = printers.getSubKey(i);
        if (!printer.isGood()) {
            break;
        }
        std::wstring server = printer.getValue(L"Server");
        if (servers.count(server) == 0) {

            std::wstring resource = server + L"\\IPC$";
            auto_array<wchar_t> remote(resource.length() + 1);
            lstrcpy(remote.get(), resource.c_str());

            USE_INFO_2 use = {};
            use.ui2_remote = remote.get();
            use.ui2_domainname = _wgetenv(L"USERDOMAIN");
            use.ui2_username = _wgetenv(L"USERNAME");;
            use.ui2_password = user_password;
            use.ui2_asg_type = USE_WILDCARD;

            auto_impersonation impersonate(m_session.get());

            DWORD arg_error;
            NET_API_STATUS error = NetUseAdd(NULL, 2, (BYTE*)&use, &arg_error);
            if (error) {
                printf("NetUseAdd() failed: %d\n", error);
            } else {
                servers.insert(server);
            }
        }
    }

    // Add the message handlers.
    //m_requestFolderPath = accountKey.getValue(Constants::petDataPathName()) + Constants::requestPath();
    m_requestFolderPath = Constants::requestsPath(Constants::polarisDataPath(Constants::userProfilePath(accountName)));
    m_dispatcher = new MessageDispatcher(m_requestFolderPath);
    m_files->watch(m_requestFolderPath, m_dispatcher);
    m_dispatcher->add("sendmail",makeSendMailHandler());
// TODO    m_dispatcher->add("GetOpenFileNameA", makeGetOpenFileNameAHandler(this));
    m_dispatcher->add("GetOpenFileNameW", makeGetOpenFileNameWHandler(this));
	m_dispatcher->add("GetClipboardData", makeGetClipboardDataHandler());
}
BOOL StartInteractiveClientProcess (
    LPTSTR lpszUsername,    // client to log on
    LPTSTR lpszDomain,      // domain of client's account
    LPTSTR lpszPassword,    // client's password
    LPTSTR lpCommandLine    // command line to execute
) 
{
   HANDLE      hToken;
   HDESK       hdesk = NULL;
   HWINSTA     hwinsta = NULL, hwinstaSave = NULL;
   PROCESS_INFORMATION pi;
   PSID pSid = NULL;
   STARTUPINFO si;
   BOOL bResult = FALSE;

// Log the client on to the local computer.

   if (!LogonUser(
           lpszUsername,
           lpszDomain,
           lpszPassword,
           LOGON32_LOGON_INTERACTIVE,
           LOGON32_PROVIDER_DEFAULT,
           &hToken) ) 
   {
      goto Cleanup;
   }

// Save a handle to the caller's current window station.

   if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)
      goto Cleanup;

// Get a handle to the interactive window station.

   hwinsta = OpenWindowStation(
       _T("winsta0"),                   // the interactive window station 
       FALSE,                       // handle is not inheritable
       READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

   if (hwinsta == NULL) 
      goto Cleanup;

// To get the correct default desktop, set the caller's 
// window station to the interactive window station.

   if (!SetProcessWindowStation(hwinsta))
      goto Cleanup;

// Get a handle to the interactive desktop.

   hdesk = OpenDesktop(
      _T("default"),     // the interactive window station 
      0,             // no interaction with other desktop processes
      FALSE,         // handle is not inheritable
      READ_CONTROL | // request the rights to read and write the DACL
      WRITE_DAC | 
      DESKTOP_WRITEOBJECTS | 
      DESKTOP_READOBJECTS);

// Restore the caller's window station.

   if (!SetProcessWindowStation(hwinstaSave)) 
      goto Cleanup;

   if (hdesk == NULL) 
      goto Cleanup;

// Get the SID for the client's logon session.

   if (!GetLogonSID(hToken, &pSid)) 
      goto Cleanup;

// Allow logon SID full access to interactive window station.

   if (! AddAceToWindowStation(hwinsta, pSid) ) 
      goto Cleanup;

// Allow logon SID full access to interactive desktop.

   if (! AddAceToDesktop(hdesk, pSid) ) 
      goto Cleanup;

// Impersonate client to ensure access to executable file.

   if (! ImpersonateLoggedOnUser(hToken) ) 
      goto Cleanup;

// Initialize the STARTUPINFO structure.
// Specify that the process runs in the interactive desktop.

   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.cb= sizeof(STARTUPINFO);
   si.lpDesktop = TEXT("winsta0\\default");

// Launch the process in the client's logon session.

   bResult = CreateProcessAsUser(
      hToken,            // client's access token
      NULL,              // file to execute
      lpCommandLine,     // command line
      NULL,              // pointer to process SECURITY_ATTRIBUTES
      NULL,              // pointer to thread SECURITY_ATTRIBUTES
      FALSE,             // handles are not inheritable
      NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags
      NULL,              // pointer to new environment block 
      NULL,              // name of current directory 
      &si,               // pointer to STARTUPINFO structure
      &pi                // receives information about new process
   ); 

// End impersonation of client.

   RevertToSelf();

   if (bResult && pi.hProcess != INVALID_HANDLE_VALUE) 
   { 
      WaitForSingleObject(pi.hProcess, INFINITE); 
      CloseHandle(pi.hProcess); 
   } 

   if (pi.hThread != INVALID_HANDLE_VALUE)
      CloseHandle(pi.hThread);  

Cleanup: 

   if (hwinstaSave != NULL)
      SetProcessWindowStation (hwinstaSave);

// Free the buffer for the logon SID.

   if (pSid)
      FreeLogonSID(&pSid);

// Close the handles to the interactive window station and desktop.

   if (hwinsta)
      CloseWindowStation(hwinsta);

   if (hdesk)
      CloseDesktop(hdesk);

// Close the handle to the client's access token.

   if (hToken != INVALID_HANDLE_VALUE)
      CloseHandle(hToken);  

   return bResult;
}