Как найти популярные имена учетных записей?
Мы все знаем, что главный на машине Administrator. Или Администратор? Или Verwalter, Administrateur, Coordinatore, Διοικητής, 管理员, 管理者? А как насчет, Remote Desktop Users, или там Guest? А иногда узнать хочется, причем в программе. Чего делать?
А делать надо вот что. Во-первых, все эти учетные записи называются well-known ("хорошо известные"), причем известные не как Бритни Спирс или ВИА Гра, а в том смысле, что есть официальный опубликованный документ, где все они перечислены. А именно, вот здесь и вот здесь.
Одно досадно, это так называемые SIDы, которые на упомянутые приятные строки ну никак не похожи. Однако, не беда, их легко перевести в строки. Зато они одни и те же на любой машине. Ну и последнее маленькое затруднение, они бывают в двух ипостасях: строковой и двоичной. Строковые - это те, что обьявлены и задокументированы, а двоичные - это те, что вам нужны. Но и это не проблема, их достаточно легко превращать друг в друга.
Таким образом, последовательность такова: берем хорошо известный SID в виде строки, например, "LA" для локального администратора или "RD" для удаленных пользователей, переводим его в бинарную форму, а потом по бинарной форме ищем имя. Делается это на С++ вот так:
#include <Windows.h>
#include <Sddl.h>
#define CHECK(api) if (!fRes) { printf("%s failed\n",api); goto exit; }
...
printf("Enter the sid to look up (string):");
WCHAR sidstr[100] = L"---";
_getws_s(sidstr,_countof(sidstr));
if (0 == sidstr[0]) break;
wprintf(L"Looking up name %s\n", sidstr);
PSID psid;
BOOL fRes = ConvertStringSidToSidW(sidstr,&psid);
CHECK("ConvertStringSidToSidW");
WCHAR wszName[256] = L"---", wszDomain[256] = L"---";
DWORD cName = _countof(wszName), cDomain = _countof(wszDomain);
_SID_NAME_USE eUse;
fRes = LookupAccountSidW(NULL,psid,wszName,&cName,wszDomain,&cDomain,&eUse);
CHECK("LookupAccountSidW");
wprintf(L"Account name: %s\nDomain: %s\n",wszName,wszDomain);
...
exit:
А в .Net и C# примерно вот так:
static String getName(String sidstr)
{
SecurityIdentifier sid = new SecurityIdentifier(sidstr);
Console.WriteLine("SID.toStr: " + sid.ToString() + " SID.value: " + sid.Value);
Type tp = typeof(NTAccount);
IdentityReference rnta = sid.Translate(tp);
Console.WriteLine("IdentityReference.value: " + rnta.Value);
return rnta.Value;
}
Как всегда, ни на что не претендую этим постом, все уже давно есть в MSDN, а только так, заметки на память плюс если кому поисковик найдет, проще будет.
[1] SID Strings: http://msdn2.microsoft.com/en-us/library/aa379602.aspx
[2] Well-knowns SIDs: http://msdn2.microsoft.com/en-us/library/aa379649.aspx