Почему UserPrincipal.Enabled возвращает разные значения?

Я пытаюсь определить, включена ли учетная запись пользователя в AD. Для этого я использую следующий код:

string domain = "my domain";
string group = "my security group";
string ou = "my OU";

//init context
using (var cnt= new PrincipalContext(ContextType.Domain, domain))
{
    //find the necessary security group
    using (GroupPrincipal mainGroup 
              = GroupPrincipal.FindByIdentity(cnt, IdentityType.Guid, group))
    {
        if (mainGroup != null)
        {
            //get the group members
            foreach (var user in mainGroup.GetMembers()
                                   .OfType<UserPrincipal>()
                                   .Where(u => u.DistinguishedName.Contains(ou)))
            {
                //ensure that all the info about the account is loaded
                //by using FindByIdentity as opposed to GetMembers
                var tmpUser= UserPrincipal.FindByIdentity(cnt, 
                                                          user.SamAccountName);
                //actually I could use `user` variable, 
                //as it gave the same result as `tmpUser`.

                //print the account info
                Console.WriteLine(tmpUser.Name + "\t" + 
                                  tmpUser.Enabled.HasValue + "\t" + 
                                  tmpUser.Enabled.Value);                    
            }
        }
    }
}

Проблема заключается в том, что когда я запускаю этот код под учетной записью администратора, я получаю реальный результат, а когда я запускаю его под непривилегированной учетной записью, user.Enabled возвращает false для некоторых учетных записей, тогда как должен быть true.

Единственное подобное q & a, которое мне удалось найти, - это

которые здесь не помогают.

Почему это так? Каковы мои возможности, чтобы получить эту информацию под непривилегированной учетной записью?


Вот еще один подход: Как определить, включена или отключена учетная запись пользователя:

private bool IsActive(DirectoryEntry de)
{
    if (de.NativeGuid == null) 
        return false;

    int flags = (int)de.Properties["userAccountControl"].Value;

    if (!Convert.ToBoolean(flags & 0x0002)) 
        return true; 
    else 
        return false;
}

Такой же подход описан в Объектах Active Directory и С#.

Однако при запуске под привилегированной учетной записью пользователя атрибут userAccountControl null, и невозможно определить состояние учетной записи.


Обходной путь здесь состоит в том, чтобы использовать PrincipalContext Constructor, указав учетные данные пользователя с достаточными привилегиями для доступа к AD.

Мне остается неясным, почему у неграмотного пользователя был доступ к AD вообще, и он не мог получить значения некоторых определенных атрибутов учетной записи. Вероятно, это не имеет ничего общего с С# и должно быть настроено в AD...

Ответ 1

Вам нужно будет делегировать разрешения в Active Directory для учетных записей, которые будут выполнять запросы AD. Это то, что я должен был сделать, чтобы мои приложения работали (хотя мы выполняем другие административные задачи в учетных записях пользователей).

Отметьте здесь о том, как делегировать разрешения (или см. блок-таблицу ниже).

Вы можете указать следующую процедуру для выполнения делегирования:

  • Запустите делегирование мастера управления, выполнив следующие шаги:
    • Откройте Active Directory - пользователи и компьютеры.
    • В дереве консоли дважды щелкните домен node.
    • В меню сведений щелкните правой кнопкой мыши организационное подразделение, выберите элемент управления делегатом и нажмите "Далее".
    • Выберите пользователей или группу, которым вы хотите делегировать общие административные задачи. Для этого выполните следующие действия:
    • На странице "Пользователи" или "Группы" нажмите "Добавить".
    • В списке "Пользователи, компьютеры или группы" укажите имена пользователей и групп, которым необходимо делегировать управление организационным подразделением, нажмите "ОК". И нажмите Далее.
    • Назначить общие задачи для делегирования. Для этого выполните следующие общие задачи.
    • В разделе "Задачи дефрагментации" нажмите "Делегировать следующие общие задачи".
    • В задачах делегирования страницы выберите задачи, которые вы хотите делегировать, и нажмите "ОК". Нажмите "Готово"

Пример. Чтобы делегировать администратора для перемещения объектов пользователя/компьютера, вы можете использовать предварительный режим в AD User and Computer и запустить делегирование. Он должен иметь права на запись в обоих OU для перемещения объекта. Для записи новых значений учетная запись администраторов должна иметь делегированные значения в учетной записи пользователя (полная привилегия в конкретном подразделении).

Что-то еще стоит посмотреть, если у учетных записей есть атрибут userAccountControl. Я слышал, что учетные записи, отсутствующие в этом атрибуте, могут не сообщать правильно. В большинстве сценариев этот атрибут должен быть установлен в NormalAccount.