2015-02-23 3 views
2

У меня возникла проблема, когда пользователь X, который является пользователем, не являющимся администратором, запускает повышенную программу, извлекает неверную информацию SID при извлечении и запросе токена связанных с текущим процессом.Получение зарегистрированного пользователя SID в многопользовательской системе пользователей

Мое основное ограничение здесь заключается в том, что я должен использовать winXP совместимый код, поэтому WSTx функций не может быть и речи.

Методы Я попытался:

  1. Я попытался извлечения SID с интерактивного рабочего стола/главного окна станции, но эти выход нечетные результаты.
  2. Expanded Env переменные: %USERPROFILE%
  3. Используется GetUserName()

Последние 2 фактически получен повышенный пользователь.

мой код:

HANDLE hTok = NULL; 
      if (false == OpenProcessToken(/*hProcess*/GetCurrentProcess(), TOKEN_QUERY, &hTok)) 
      { 
       LOG_ERROR(L"Failed obtaining process' token"); 
       return false; 
      } 

      // get user info size 
      LPBYTE pBuf = nullptr; 
      DWORD dwSize = 0; 
      bool bSuccess = false; 
      if (false == GetTokenInformation(hTok, TokenUser, NULL, 0, &dwSize)) 
      { 
       if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) 
       { 
        LOG_ERROR(L"Failed getting token information"); 
        return false; 
       } 
      } 

      do 
      { 
       pBuf = (BYTE*)::LocalAlloc(LPTR, dwSize); 
       if (nullptr == pBuf) 
       { 
        LOG_ERROR(L"Failed allocating buffer for token information"); 
        break; 
       } 

       WCHAR* pSid = nullptr; 
       if (GetTokenInformation(
        hTok, 
        TokenUser, 
        pBuf, 
        dwSize, 
        &dwSize)) 
       { 
        PTOKEN_USER pUserToken = reinterpret_cast<PTOKEN_USER>(pBuf); 
        if (false == ConvertSidToString(pUserToken->User.Sid, &pSid)) 
        { 
         LOG_ERROR(L"Failed converting sid to string"); 
         break; 
        } 

        bSuccess = true; 
        ::LocalFree(pSid); 
       } 
      } while (false); 

      if (pBuf) 
       ::LocalFree(pBuf); 

      if (hTok && INVALID_HANDLE_VALUE != hTok) 
       ::CloseHandle(hTok); 

      return bSuccess; 

Еще одна идея, которую я имел в виду, чтобы открыть explorer.exe «s маркер, но я столкнулся с другой проблемой, когда 2 пользователи вошли в систему, как я могу различать между запущенными explorer.exe с сейчас?

Edit: Если я получить SID с помощью GetUserObjectInformation активного рабочего стола с UOI_USER_SID, я получаю сеанс входа в систему, которая 20 в длину, можно ли каким-то образом перевести этот сеанс входа в систему в сеансе пользователя?

+0

Функции WTS были вокруг с Windows 2000, на самом деле. Попробуйте использовать 'WTSQuerySessionInformation()' для запроса 'WTSUserName' и' WTSDomainName', затем передайте эти значения 'LookupAccountName()' для получения SID. –

ответ

0

Функции WTS вокруг с Windows 2000.

Я могу придумать несколько подходов к проблеме. Ваш возвышенный процесс может:

  1. использование WTSQuerySessionInformation() для запроса текущей сессии для WTSUserName/WTSDomainName или WTSSessionInfo (который также предоставляет домен/пользователь), а затем передать эти значения LookupAccountName() получить SID этого пользователя.

  2. использование OpenDesktop(), чтобы открыть текущий рабочий стол, а затем использовать GetUserObjectInformation() запросить его UOI_USER_SID.

  3. создать отдельную службу работает в учетной записи LocalSystem, который использует WTSQueryUserToken(), чтобы получить маркер пользователя текущего сеанса (ваше приложение может передать свой текущий SessionID на службу, чтобы знать, какую сессию для запроса), а затем использовать GetTokenInformation() для запроса его TokenLogonSid и передать SID обратно в ваше приложение.

+0

Спасибо Remy за быстрый ответ, несколько комментариев относительно вашего ответа: 1. https://msdn.microsoft.com/en-us/library/aa383838%28v=vs.85%29.aspx четко заявляет, что минимум поддерживается клиентская версия - Windows Vista 2.UOI_USER_SID предоставляет сеанс входа в систему, который является хорошо известным SID, отформатированным как 20 символов SID, тот, который я пытаюсь извлечь, имеет длину 36 символов. 3. как 1 –

+0

На первый взгляд, похоже, что, поскольку Microsoft пренебрегала поддержкой winXP, они обновили минимальную поддержку версии Vista. –

+2

@igalk: К сожалению, вы не можете доверять минимальным версиям ОС, указанным в MSDN. Всякий раз, когда Microsoft отказывается от поддержки данной ОС, они обычно проходят всю документацию MSDN и подгоняют минимальные версии в документах API. Таким образом, в большинстве случаев MSDN ** не говорит о том, какая версия ОС, какой-либо данный API ** была введена в **, только в той версии ОС, которая по-прежнему поддерживается ** в **, это не то же самое. Это очень раздражает. –

Смежные вопросы