Моя проблема
Я использую функции PInvoked Windows API, чтобы проверить, входит ли пользователь в группу локальных администраторов.Я использую GetCurrentProcess
, OpenProcessToken
, GetTokenInformation
и LookupAccountSid
, чтобы проверить, является ли пользователь локальным администратором.
GetTokenInformation
возвращает структуру TOKEN_GROUPS
с массивом структур SID_AND_ATTRIBUTES
.Я перебираю коллекцию и сравниваю имена пользователей, возвращаемые LookupAccountSid
.
Моя проблема заключается в том, что локально (или, в более общем случае, в нашем внутреннем домене), это работает как ожидалось.Встроенный \ Администраторы находится в составе группы текущего маркера процесса, и мой метод возвращает значение true.В другом домене другого разработчика функция возвращает false.
LookupAccountSid
работает правильно для первых двух итераций структуры TOKEN_GROUPS
, возвращая None и Everyone, а затем выдает жалобу, что «Параметр неверен».
Что может заставить правильно работать только две группы?
Структура TOKEN_GROUPS
указывает на наличие 14 групп.Я предполагаю, что это SID, который является недействительным.
Все, что я PInvoked, я взял из примера на сайте PInvoke .Единственное отличие состоит в том, что с LookupAccountSid
я изменил параметр Sid
с byte[]
на IntPtr
, потому что SID_AND_ATTRIBUTES
также определяется с IntPtr
.Это нормально, поскольку LookupAccountSid
определяется с помощью PSID?
LookupAccountSid PInvoke
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool LookupAccountSid(
string lpSystemName,
IntPtr Sid,
StringBuilder lpName,
ref uint cchName,
StringBuilder ReferencedDomainName,
ref uint cchReferencedDomainName,
out SID_NAME_USE peUse);
Где код падает
for (int i = 0; i < usize; i++)
{
accountCount = 0;
domainCount = 0;
//Get Sizes
LookupAccountSid(null, tokenGroups.Groups[i].SID, null, ref accountCount, null,
ref domainCount, out snu);
accountName2.EnsureCapacity((int) accountCount);
domainName.EnsureCapacity((int) domainCount);
if (!LookupAccountSid(null, tokenGroups.Groups[i].SID, accountName2, ref accountCount, domainName,
ref domainCount, out snu))
{
//Finds its way here after 2 iterations
//But only in a different developers domain
var error = Marshal.GetLastWin32Error();
_log.InfoFormat("Failed to look up SID's account name. {0}", new Win32Exception(error).Message);
continue;
}
Если понадобится больше кода, дайте мне знать.Любая помощь будет принята с благодарностью.