Windows 2008上的.NET Active Directory密码过期

时间:2010-03-12 02:51:18

标签: c# .net active-directory windows-server-2008 passwords

搜索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的例子匹配。

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

1 个答案:

答案 0 :(得分:2)

存储密码到期时间,如果lastPwdSet - maxPwdAge < DateTime.UtcNow为真,则密码已过期。因此,如果您在一周前设置了密码,但密码将在10天后过期,则左侧将为(DateTime.UtcNow - 7) - (-10),或DateTime.UtcNow - 7 + 10DateTime.UtcNow + 3,且不小于{ {1}},因此您的密码不会过期。

这意味着将maxPwdAge设置为long.MinValue将有效地为您提供数千年的密码到期时间。因此,如果您收到DateTime.UtcNow,则您的政策会说密码不会过期。你应该只是寻找那个值并正确对待它,可能是这样的:

long.MinValue

另外,我应该指出,这些值以100纳秒的增量存储,因此您应该期望数十亿的值。