Получить основную группу из UserPrincipal C#

Я хочу найти основную группу из кода ниже

Я могу получить все группы для пользователя, но какая из них является основной?

        string primaryGroupName = String.Empty;
        using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
        {
            using (UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "userName"))
            {
                foreach (Principal p in user.GetGroups())
                {
                    WriteLog("PrimaryGroup Name(s)???:");
                    WriteLog(p.Name);
                    primaryGroupName = p.Name;
                }
            }
        }

Что возвращается из приведенного выше кода...

Пользователи домена
Администраторы
Администраторы схемы
Администраторы предприятия
Администраторы домена
...и еще несколько

Что такое основная группа?


person nlstack01    schedule 11.07.2019    source источник
comment
Вы можете получить идентификатор основной группы, но я не знаю, как оттуда перейти к названию группы. var userEntry = user.GetUnderlyingObject() as DirectoryEntry; var primaryGroupId = userEntry.Properties["primaryGroupID"].Value;   -  person    schedule 11.07.2019
comment
@Amy Спасибо, кажется, это дало мне идентификатор (например, 513), теперь, как мне использовать идентификатор, чтобы получить имя группы?   -  person nlstack01    schedule 11.07.2019
comment
Я сказал, что не знаю, как это сделать, извините.   -  person    schedule 11.07.2019
comment
Возможно ли, что последние цифры SID являются идентификатором? Сид=S-1-5-21-ххххххххх-хххххххх-ххххххххх-513   -  person nlstack01    schedule 11.07.2019


Ответы (1)


У вас есть правильная идея: primaryGroupID содержит RID (относительный идентификатор) группы, которая является основной группой. RID — это последний набор чисел в SID. Остальная часть SID идентифицирует домен. Таким образом, вы можете определить SID группы, используя SID пользователя и primaryGroupID.

Я написал пару статей об этом. Один назывался Что делает участника участником. ? с разделом, описывающим основную группу. А также статья под названием Поиск всех групп пользователя, где я поделился кодом для поиска основной группы. Я обнаружил, что прямое использование DirectoryEntry всегда быстрее, чем использование UserPrincipal/GroupPrincipal, так что это то, что используется в моих примерах:

Вот метод:

private static string GetUserPrimaryGroup(DirectoryEntry de) {
    de.RefreshCache(new[] {"primaryGroupID", "objectSid"});

    //Get the user's SID as a string
    var sid = new SecurityIdentifier((byte[])de.Properties["objectSid"].Value, 0).ToString();

    //Replace the RID portion of the user's SID with the primaryGroupId
    //so we're left with the group's SID
    sid = sid.Remove(sid.LastIndexOf("-", StringComparison.Ordinal) + 1);
    sid = sid + de.Properties["primaryGroupId"].Value;

    //Find the group by its SID
    var group = new DirectoryEntry($"LDAP://<SID={sid}>");
    group.RefreshCache(new [] {"cn"});

    return group.Properties["cn"].Value as string;
}

Чтобы использовать это из своего кода, вы должны сделать следующее:

var primaryGroupName = GetUserPrimaryGroup((DirectoryEntry) user.GetUnderlyingObject());

Этот метод просто возвращает имя группы, но вы можете изменить его по своему усмотрению.

Все это говорит о том, что 513 всегда является RID встроенной группы пользователей домена.

person Gabriel Luci    schedule 16.07.2019