さて、パスワードの最小有効期間と履歴ポリシーが適用されているシナリオで、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 を使用することはできません (パスワード履歴を尊重しないため)。