Срок действия пароля .NET Active Directory в Windows 2008

Искал SO и везде, включая руководство разработчиков .net по программированию служб каталогов - безуспешно.

Я пытаюсь создать простую веб-страницу сброса пароля, которая позволяет пользователю изменить свой пароль. Часть кода смены пароля работает нормально. Для пользователей я также хотел бы показать, когда истечет срок действия их текущего пароля.

Используя пример кода из книги, упомянутой выше, я смог получить всю настройку кода, однако возвращаемый атрибут всегда равен Long.MinValue и, следовательно, не может быть инвертирован в положительное число, плюс это означает, что он не нашел правильная настройка домена.

Есть ли у кого-нибудь пример кода или ссылки для получения срока действия пароля в среде домена Windows 2008 или R2, где политики паролей могут быть разными для каждого пользователя?

Обновлено для включения кода

Конструктор, который получает объект политики:

public PasswordExpires()
    {
        //Get Password Expiration
        Domain domain = Domain.GetCurrentDomain();
        DirectoryEntry root = domain.GetDirectoryEntry();

        using (domain)
        using (root)
        {
            this.policy = new DomainPolicy(root);
        }
    }

Конструктор политики домена:

public DomainPolicy(DirectoryEntry domainRoot)
    {
        string[] policyAttributes = new string[] {
  "maxPwdAge", "minPwdAge", "minPwdLength", 
  "lockoutDuration", "lockOutObservationWindow", 
  "lockoutThreshold", "pwdProperties", 
  "pwdHistoryLength", "objectClass", 
  "distinguishedName"
  };

        //we take advantage of the marshaling with
        //DirectorySearcher for LargeInteger values...
        DirectorySearcher ds = new DirectorySearcher(
          domainRoot,
          "(objectClass=domainDNS)",
          policyAttributes,
          SearchScope.Base
          );

        SearchResult result = ds.FindOne();

        //do some quick validation...         
        if (result == null)
        {
            throw new ArgumentException(
              "domainRoot is not a domainDNS object."
              );
        }

        this.attribs = result.Properties;
    }

Вызовите этот метод, чтобы получить срок действия пароля:

public TimeSpan MaxPasswordAge
    {
        get
        {
            string val = "maxPwdAge";
            if (this.attribs.Contains(val))
            {
                long ticks = GetAbsValue(
                  this.attribs[val][0]
                  );

                if (ticks > 0)
                    return TimeSpan.FromTicks(ticks);
            }

            return TimeSpan.MaxValue;
        }
    }

Код здесь дает сбой, потому что он не может преобразовать Long.MinValue, чего не должно быть в первую очередь.

private long GetAbsValue(object longInt)
    {
        return Math.Abs((long)longInt);
    }

Вот вывод и значения отладчика. Согласно сайту MSDN, исключение переполнения вызвано минимальным значением. Мои числа соответствуют примерам для minvalue.

http://www.brentpabst.com/capture.png


person Brent Pabst    schedule 12.03.2010    source источник
comment
Истечение срока действия пароля — это вопрос групповой политики, не так ли?   -  person zneak    schedule 12.03.2010
comment
@gabe Обновил его, чтобы включить код. Все, что у вас есть, полезно. @zneak управляется с помощью групповой политики, но доступен через LDAP и другие механизмы.   -  person Brent Pabst    schedule 12.03.2010
comment
Откуда вы знаете, что это не удается из-за получения long.MinValue?   -  person Gabe    schedule 12.03.2010
comment
И вообще, зачем тебе делать Abs? Это не имеет смысла.   -  person Gabe    schedule 12.03.2010
comment
@gabe Я добавил ссылку на скриншот отладчика, чтобы показать вам значение и исключение. Я следовал примеру из книги, на которую ссылаются, где они инвертируют значения, потому что они утверждают, что они хранятся как отрицательные числа. Я ожидаю, что число намного меньше, например 1061029, а не огромное длинное. Я недостаточно знаю о том, как AD хранит атрибут, чтобы сказать вам, почему он будет отрицательным, отсюда и справочник.   -  person Brent Pabst    schedule 12.03.2010
comment
Возможно, ваши пароли настроены на неограниченный срок действия. Можете ли вы увидеть, что такой инструмент, как adfind, ldife или ldp, сообщает вам об этом свойстве?   -  person Gabe    schedule 12.03.2010
comment
@gabe я идиот. Ранее я изменил настройки тестового домена, чтобы работать с другой настройкой. После обновления объекта групповой политики и его выталкивания все кажется решенным. Знаете ли вы, есть ли определенные вещи, которые вы должны учитывать при рассмотрении контроллера 2008 года в отличие от более старого контроллера из-за того, как распределяются политики?   -  person Brent Pabst    schedule 12.03.2010


Ответы (1)


Время истечения срока действия пароля хранится таким образом, что если lastPwdSet - maxPwdAge < DateTime.UtcNow верно, срок действия вашего пароля истек. Таким образом, если вы установили свой пароль неделю назад, но срок действия пароля истекает через 10 дней, слева будет (DateTime.UtcNow - 7) - (-10), или DateTime.UtcNow - 7 + 10, или DateTime.UtcNow + 3, что не меньше DateTime.UtcNow, поэтому срок действия вашего пароля не истечет.

Это означает, что установка для maxPwdAge значения long.MinValue фактически даст вам тысячи лет до истечения срока действия вашего пароля. Поэтому, если вы получаете long.MinValue, ваша политика говорит, что срок действия паролей не ограничен. Вы должны просто найти это значение и обработать его должным образом, возможно, так:

private long GetAbsValue(object longInt)  // poorly named
{
    long val = (long)longInt;
    if (val == long.MinValue)
        return long.MaxValue;
    return Math.Abs((long)longInt);  
}

Кроме того, я должен отметить, что значения хранятся с шагом в 100 наносекунд, поэтому вы должны ожидать значений в миллиардах.

person Gabe    schedule 12.03.2010