2016-09-07 3 views
3

Мне нужно получить строковый формат SID зарегистрированного пользователя. У меня уже есть имя пользователя и я пытаюсь использовать LookupAccountName для получения SID. Это работает частично - я получаю SID, но это лишь частичное совпадение с фактическим SID пользователя.Как получить идентификатор SID для входа в систему в Windows

Я не хочу, чтобы SID владельца процесса, поскольку процесс может быть повышен (олицетворяется), но я хочу, чтобы SID пользователя, который вошел в систему, где выполняется процесс.

Код должен работать с невыполненными привилегиями.

Это мой код до сих пор

LPCTSTR wszAccName = TEXT("hardcoded username for testing"); 
LPTSTR wszDomainName = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) * 1024); 
DWORD cchDomainName = 1024; 
SID_NAME_USE eSidType; 
SID sid; 
DWORD cbSid = 1024; 
if (!LookupAccountName(NULL, wszAccName, &sid, &cbSid, wszDomainName, &cchDomainName, &eSidType)) { 
    return GetLastError(); 
} 

if (!ConvertSidToStringSid(&sid, &pszSidBuffer)) { 
    return GetLastError(); 
} 

Это дает SID как "S-1-5-21-1-1234567890-9-1000" Но фактический SID пользователя, как «S- 1-5-21-3214321539-1234567890-2233445522-1000 " (в соответствии с владельцем процесса и ключом реестра под HKEY_USERS). Обратите внимание, что SID одинаковы, за исключением 5-го и 7-го компонентов, которые имеют только 1 цифру, но должны быть длиннее.

Как получить фактический/полный идентификатор пользователя?

Кроме того, я являюсь новичком C/C++ (и код выше не является качеством производства вообще). И я использую/NODEFAULTLIB, чтобы избежать связывания времени выполнения VC. Извини за это.

+0

Похоже, что SID, который вы получаете с этим кодом, имеет другой домен/локальный идентификатор. Как вы определяете «фактический SID пользователя», с которым вы его сравниваете? Связана ли машина с доменом? –

+0

@CodyGray Обновлен вопрос. По фактическому SID я имею в виду тот, который я просматриваю, глядя на владельца процесса (код не показан) или просмотрев раздел реестра пользователя под HKEY_USERS. – Blaze

+0

Похоже, что WTSQueryUserToken был бы очень полезен, поскольку я мог бы получить SessionID (не путать с SID) с использованием функций WTS, а затем получить SID из токена пользователя. Однако WTSQueryUserToken требует специальных prvilieges (т. Е. Услуги), тогда как мне нужно, чтобы это работало в обычном, не повышающемся процессе. – Blaze

ответ

3

Ваш код не содержит буфера надлежащего размера для SID, возвращаемого LookupAccountName(). Это приводит к повреждению стека и неопределенному поведению, которое может, по-видимому, объяснить, почему вы не получаете SID, которого вы ожидали. (. Хотя я подозреваю, что вы на самом деле проходит в неправильном имени пользователя, или неправильно отформатирована имя пользователя)

В любом случае, чтобы исправить наиболее очевидные проблемы, код должен выглядеть следующим образом:

#include <Windows.h> 
#include <Sddl.h> 

#include <stdio.h> 

int main(int argc, char ** argv) 
{ 
    LPCTSTR wszAccName = TEXT("domainname\\username"); 
    LPTSTR wszDomainName = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) * 1024); 
    DWORD cchDomainName = 1024; 
    SID_NAME_USE eSidType; 
    LPTSTR sidstring; 
    char sid_buffer[1024]; 
    DWORD cbSid = 1024; 
    SID * sid = (SID *)sid_buffer; 

    if (!LookupAccountName(NULL, wszAccName, sid_buffer, &cbSid, wszDomainName, &cchDomainName, &eSidType)) { 
     return GetLastError(); 
    } 

    if (!ConvertSidToStringSid(sid, &sidstring)) { 
     return GetLastError(); 
    } 

    printf("%ws\n", sidstring); 
    return 0; 

} 

Это, конечно, не правильный способ сделать это; вы должны дважды вызвать LookupAccountName(), один раз, чтобы определить длину буфера, а затем второй раз для получения фактической информации. Но он демонстрирует, что вы сделали неправильно, и достаточно хорош для тестирования.

+0

Спасибо! Это работало так, что это был мой неправильный размер буфера, который вызвал странный результат (имя учетной записи, которое я использовал, было по строкам «Dave-PC \\ Dave», что было правильно). – Blaze

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