У меня проблемы с C ++, я не часто использую этот язык!
Я пытаюсь обработать списки ACL в каталоге NTFS, чтобы вывести полный список всех разрешенных и запрещенных разрешений, существующих в каталоге.
У меня есть списки ACL из каталога, и для большинства записей у меня есть имя домена \ учетной записи. Однако в некоторых случаях вывод этой команды дает мне ???????? \ ????????.
Я определил 2 причины для этого.
1) учетная запись пользователя была удалена с компьютера, поэтому SID является бесхозным. Я могу определить это с GetLastError () = 1332.
2) это «общеизвестный SID», т. Е. Какой-то встроенный SID, поэтому имя пользователя для сопоставления отсутствует — LookupAccountSid не сообщает об ошибке на этом этапе. У меня нет способа (насколько я вижу) идентифицировать эти случаи, не отображая все известные идентификаторы безопасности в файл и не делая перекрестные ссылки (медленно). Что я хочу сделать, это просто вывести SID вместо ????????. LPTSTR myTrusteeName — это строка, возвращаемая LookupAccountSid (), которая отображается как ???????? Я не знаю, каково его действительное значение, если бы я знал, что мог бы легко сделать оператор IF, чтобы вместо этого напечатать SID.
//this is part of a loop.
if (IsValidSid(mySid)){
//cout << "SID supplied is valid\n";
//cout << GetLengthSid(mySid) << "\n";
LPWSTR mySidName = NULL;
ConvertSidToStringSid((PSID)mySid, &mySidName);//Make an initial lookup to find out how big the names are
LookupAccountSid(
NULL
, (PSID) mySid
, myTrusteeName
, (LPDWORD)&myDwordNameLength
, myDomainName
, (LPDWORD)&myDwordDomLength
, &myNameUse
); //at this point error 122 is thrown as the length of myTrusteeName is too short.
//alter the size of these variables rather than just getting the 1st letter and some gibberish
myTrusteeName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordNameLength);
myDomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordDomLength);
//do the lookup again this time with genuine sizes
LookupAccountSid(
NULL
, (PSID)mySid
, myTrusteeName
, (LPDWORD)&myDwordNameLength
, myDomainName
, (LPDWORD)&myDwordDomLength
, &myNameUse
);
wcout << GetLastError() << "\n"; //this will output "122" even when successful because of the first attempt.
_tprintf(TEXT("%s\n"), myTrusteeName); //when there is no name this outputs ????????
wcout << myTrusteeName << "\n"; //when there is no name this completely screws myTrusteeName so that it fails to print for the rest of the loop//if we only have ???? then it's wrong
if (myTrusteeName == NULL){ /// WHAT IN HELL DO I PUT IN THIS COMPARISON TO IDENTIFY myTrusteeName VALUES THAT PRINT ????????
wcout << "we are changing trustee because it's blank\n";
myTrusteeName = _T("");//maybe change this to the value of mySidName
wcout << "length of trustee is now " << _tcslen(myTrusteeName) << "\n";
}
wcout << "\n";}
Теперь … во время написания этого я понимаю, что есть функция под названием IsWellKnownSid () Facepalm
Это выводит элемент из WELL_KNOWN_SID_TYPE перечисление
Я должен быть в состоянии использовать это …. Я не уверен, как я могу получить строковое представление хорошо известного типа sid (то есть «Пользователи»), как вы уже видели в редакторе ACL …. Если У кого-нибудь есть какие-либо советы по этому поводу, я был бы очень благодарен.
Я еще не закончил с этим небольшим проектом, поэтому я решил опубликовать его в любом случае, если он окажется полезным для кого-то еще в будущем!
Мне все еще любопытно — если бы не было функции IsWellKnownSid (), как бы я обнаружил строковое значение, которое отказывается печатать, ДО ТОГО, как я пытаюсь его напечатать?
Большое спасибо за чтение и наилучшие пожелания
Бен
Вы должны проверить это ConvertSidToStringSid
а также LookupAccountSid
вернуть ИСТИНА. Если они это сделают, тогда LookupAccountSid записывает строку в myTrusteeName
, Если LookupAccountSid возвращает FALSE, тогда LookupAccountSid не будет изменять содержимое myTrusteeName
так что это будет так же неинициализировано, как GlobalAlloc
вернул его.