У меня есть SID учетной записи пользователя, и я хочу SID групп, которым он принадлежит
Это должно быть получено с удаленной машины. Следующий запрос работает не для идентификаторов безопасности, а для имен групп и учетных записей.
"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""
Объекты Win32_Group, которые он возвращает, представлены в виде строк, и у них есть только домен и имя (даже если Win32_Group имеет свойство SID).
У меня такое чувство, что мне придется:
- Превратите SID в имя учетной записи, запросив Win32_SID;
- Выполните запрос выше;
- Превратите каждое из полученных имен групп в SID, запросив Win32_Group.
2 ответа
Можете ли вы использовать классы пространства имен System.DirectoryServices.AccountManagement?
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, accountName ))
{
var groups = user.GetAuthorizationGroups();
...iterate through groups and find SIDs for each one
}
}
Он должен работать с ContextType.Machine, хотя вам нужно будет указать имя компьютера и иметь соответствующие привилегии.
using (var context = new PrincipalContext( ContextType.Machine,
"MyComputer",
userid,
password ))
{
...
}
Есть хорошая статья MSDN (хотя и длинная) об использовании нового пространства имен управления учетными записями.NET 3.5.
Да, но некоторые методы зависят от наличия домена.
См. Эту страницу, чтобы узнать, как преобразовать SID в идентификатор пользователя с помощью P/Invoke и Windows API или с.NET 2.0+ и без P/Invoke.
using System.Security.Principal;
// преобразовать sid пользователя в домен \name string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();
Если у вас есть AD и идентификатор пользователя, используйте метод DirectorySearcher или API управления учетными записями, чтобы найти группы. В противном случае используйте метод, описанный в этой статье, чтобы получить локальные группы.
- Теперь используйте API, предложенный @tvanfosson, для итерации групп и получения идентификаторов безопасности. Или следуйте информации ниже.
В приложении ASP.NET можно использовать подобный код для доступа к информации о группе при условии, что пользователь проходит проверку подлинности Windows, а не проверку подлинности с помощью форм. В этом примере я оставил интересную заметку об исключениях, которые генерируются в этой среде, но это может относиться к другим пользователям:
public List<string> GetGroupsFromLogonUserIdentity()
{
List<string> groups = new List<string>();
HttpRequest request = HttpContext.Current.Request;
if (request.LogonUserIdentity.Groups != null)
{
foreach (IdentityReference group in request.LogonUserIdentity.Groups)
{
try
{
groups.Add(group.Translate(typeof(NTAccount)).ToString());
}
catch (IdentityNotMappedException)
{
// Swallow these exceptions without throwing an error. They are
// the result of dead objects in AD which are associated with
// user accounts. In this application users may have a group
// name associated with their AD profile which cannot be
// resolved in the Active Directory.
}
}
}
return groups;
}
LogonUserIdentity основан на классе WindowsIdentity. Вы можете изменить мой пример кода, чтобы использовать WindowsIdentity и функционировать в не-веб-приложении. Как только вы перебираете группу, вы можете сделать что-то вроде этого, чтобы получить SecurityIdentifier:
SecurityIdentifier secid = group as SecurityIdentifier;