Как независимая DLL может узнать, с каким файлом токена будет осуществляться доступ?

Если родительский процесс использовал LogonUser, так что маркер доступа, используемый для доступа к файлу, отличается от маркера, с которым был запущен процесс, как DLL может узнать имя пользователя NT, под которым будет обрабатываться доступ к файлу?

Если бы у меня было конкретное расположение файла, я мог бы использовать GetFileSecurity, однако я не знаю никаких гарантированных доступных путей в контексте DLL.

Если бы я использовал следующее:

PSID ownedSID(NULL);
SECURITY_INFORMATION siRequested = OWNER_SECURITY_INFORMATION;
wSecInfoOK = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, siRequested, &ownedSID, NULL, NULL, NULL, NULL);

тогда возвращаемый PSID ссылается на пользователя Windows вошедшего в систему процесса, а не на того, под которым будут обрабатываться любые записи!

Новый вопрос в легком комментарии / ответе от @arx

Теперь я использую TokenUser с GetTokenInformation в дескрипторе из OpenThreadToken, но снова я получаю запускающего пользователя, но не олицетворяемого пользователя

HANDLE hThreadToken = NULL;
if (OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hThreadToken))
{
// success

    CHeapPtr<TOKEN_USER, CGlobalAllocator> pToken;
    DWORD length = 0U, dwError(0UL);
    if (!GetTokenInformation(hThreadToken, TokenUser, NULL, 0, &length) && ERROR_INSUFFICIENT_BUFFER == GetLastError())
    {
        pToken.AllocateBytes(length);
        SetLastError(ERROR_SUCCESS);//Reset last error - we have now allocated the required memory so the buffer is now big enough i.e GetLastError() != ERROR_INSUFFICIENT_BUFFER
        if (pToken && GetTokenInformation(hThreadToken, TokenUser, pToken, length, &length)) 
        {
            if (IsValidSid(pToken->User.Sid))
                sFailedUser = WinSecurityInfo::GetAccountSID(pToken->User.Sid, dwError);
        }
        dwError = GetLastError();
        if (dwError)
        {
            boost::system::error_code sidError = MakeSysError(dwError);
            TRACE("Error text for GetLastError() = '%s'\n", sidError.message().c_str());
        }
    }
}

P.S. WinSecurityInfo::GetAccountSID — это всего лишь оболочка вокруг LookupAccountSid. P.S. Пробовал как FALSE, так и TRUE в OpenThreadToken, без изменений.


person Peter Nimmo    schedule 07.04.2014    source источник
comment
Похоже на проблему XY. Почему ваша DLL заботится о токене доступа?   -  person Eric Brown    schedule 07.04.2014
comment
+1, почему? В любом случае, OpenThreadToken.   -  person arx    schedule 08.04.2014
comment
У нас есть внепроцессный COM-сервер, которому необходимо вести журнал на диск, однако мы обнаружили, что в зависимости от того, как этот сервер запущен, он оказывает прямое влияние на то, будет ли работать журналирование на диск. Когда он запущен из службы Windows, он не регистрируется. Я хочу добавить событие в журнал событий, описывающий, под каким пользователем Windows выполняется попытка доступа к файлу. В реальном мире олицетворение не происходит, поэтому SID токена процесса будет таким же, как и on, используемый для доступа к файлу, но я хотел сделать его надежным по отношению к используемому олицетворению.   -  person Peter Nimmo    schedule 08.04.2014
comment
Пробовал OpenThreadToken, но я все еще получаю пользователя запуска, а не олицетворенного пользователя. В качестве теста я записал файл в несопоставленное место, и Владелец по-прежнему является пользователем запуска. Таким образом, это должен быть олицетворенный пользователь, которого мне нужно обнаружить, чтобы люди могли сказать из журнала событий, почему было невозможно записать в сопоставленное местоположение.   -  person Peter Nimmo    schedule 08.04.2014


Ответы (1)


Вы видите неверную информацию в токене потока, полученном с помощью OpenThreadToken. Чтобы получить личность выдающего себя пользователя, вам нужно просмотреть файл TokenUser, а не TokenOwner.

Используйте GetTokenInformation восстановить пользователя.

Однако вместо того, чтобы идти на все, чтобы работать в условиях олицетворения, обычно в рамках вашего контракта с API указывается, что вы этого не делаете. А потом игнорировать проблему.

person arx    schedule 08.04.2014