0

さて、パスワードの最小有効期間と履歴ポリシーが適用されているシナリオで、DirectoryEntry と LdapConnection を使用してパスワードをリセットしています。誰かがパスワードを忘れた場合、パスワード履歴に違反しないパスワードにパスワードをリセットできるようにしたいと考えています。別の解決策として、「SetPassword」を使用してパスワードを生成された値にリセットし、ユーザーが次回のログイン時にパスワードを変更するように強制することができます。これは、私たちのシナリオでは不可能です。そのため、 technet のこのブログ投稿をフォローし、パスワード履歴を尊重してパスワードをリセットするための LDap 拡張コントロールを試していました。簡単に言えば、同じパスワードに何度も何度も変更するだけで、文句はありません。私のコードは次のとおりです。

 private static void PasswordChanger(DirectoryConnection ldapCon, 
        string distinguishedName, 
        string passwordToSet = null)
    {
        // the 'unicodePWD' attribute is used to handle pwd handling requests
        // modification control for the replace operation
        var damReplace = new DirectoryAttributeModification
        {
            Name = "unicodePwd"
        };

        // value to be send with the request
        damReplace.Add(Encoding.Unicode.GetBytes(String.Format("\"{0}\"", passwordToSet)));

        // this is a replace operation
        damReplace.Operation = DirectoryAttributeOperation.Replace;

        // combine modification controls
        var damList = new DirectoryAttributeModification[]
        {
            damReplace
        };

        // init modify request
        var modifyRequest = new ModifyRequest(distinguishedName, damList);

        // the actual extended control OID 
        const string ldapServerPolicyHintsOid = "1.2.840.113556.1.4.2239";

        // build value utilizing berconverter
        var value = BerConverter.Encode("{i}", new object[] { 0x1 });

        // init exetnded control. The variable name represts the actual extended control name.
        var LDAP_SERVER_POLICY_HINTS_OID = new DirectoryControl(ldapServerPolicyHintsOid, 
            value, false, true);

        // add extended control to modify request
        modifyRequest.Controls.Add(LDAP_SERVER_POLICY_HINTS_OID);

            /* send the request into the LDAPConnection and receive the response */
        var result = ldapCon.SendRequest(modifyRequest);
    }

Password changer への呼び出しは、次のように囲まれています。

                using (var domain = Domain.GetDomain(new DirectoryContext(
                    DirectoryContextType.DirectoryServer,
                    ActiveDirectoryInstance,
                    request.ServiceAccountName,
                    request.ServiceAccountPassword)))
                using (var directoryEntry = domain.GetDirectoryEntry())
                using (var directorySearcher = new DirectorySearcher(directoryEntry))
                using (var conn = new LdapConnection(new LdapDirectoryIdentifier(ActiveDirectoryInstance), 
                    new NetworkCredential(request.ServiceAccountName, 
                        request.ServiceAccountPassword, 
                        ActiveDirectoryInstance), 
                        AuthType.Ntlm))
                {
                    ...
                    ...

                    PasswordChanger(....)
                    ...
                    ...
                }

編集:

これは、ここで説明されているシナリオと関係があります

https://support.microsoft.com/en-us/kb/2386717/

RE 私のコメント re 「別の解決策として、「SetPassword」を使用してパスワードを生成された値にリセットし、ユーザーが次回のログイン時にパスワードを変更するように強制することができます。」

このシナリオでは、パスワード履歴と最低年齢制限 (24 時間) が有効になっているため、これを行うことはできません。したがって、ユーザー コンテキストで ChangePassword を使用し、管理コンテキストで SetPassword を使用することはできません (パスワード履歴を尊重しないため)。

4

1 に答える 1