MSDN:UserAccountControl フラグを使用してユーザー アカウント プロパティを操作する方法にある UserAccountControl フラグで、PASSWD_CANT_CHANGE フラグ(0x0040) を使って仕様と思ったが、これは使えませんでした。
上記MSのページにも注意事項として「注 : UserAccountControl 属性を直接変更することでこのアクセス許可を割り当てることはできません。プログラムを使用してアクセス許可を設定する方法の詳細については、この資料の「プロパティ フラグの説明」を参照してください。 」とあります。
説明ページへのリンクがあるんですがは英文で読めません。。。
で、見つけたのが、[ADSI] Active Directory 環境でユーザはパスワードを変更できないオプションをコントロールする - ComponentGeek Articleです。(このサイトはActiveDirectory操作に関する情報が満載で助かってます。)
パスワードオプションの変更には、ActiveDirectoryAccessRule クラスとやらを使わないといけないようですね。
ほぼ参考先のソースと同じですが、一応のっけておきます。(C#, LINQ使ってるので.Net3.5以上となります。)
///
/// パスワードの変更の許可・拒否を行う。
///
/// ユーザーオブジェクトのパス
/// True:パスワード変更許可 False:パスワード変更拒否
private void SetCannotChangePassword(string path, bool allowChangePassword)
{
//Pathからオブジェクト取得
DirectoryEntry dEntUsr = new DirectoryEntry(path, cUser, cPasswd);
//DirectoryEntry dEntUsr = (DirectoryEntry)entry.NativeObject;
// パスワードの変更を許可,拒否する、特別なタスクの実行を許可するための権利を表すオブジェクトのGUID
Guid changePasswordGuid = new Guid("AB721A53-1E2F-11D0-9819-00AA0040529B");
// Everyoneのセキュリティ識別子
SecurityIdentifier everyoneSid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
// NT AUTHORITY\SELFのセキュリティ識別子.
SecurityIdentifier selfSid = new SecurityIdentifier(WellKnownSidType.SelfSid, null);
//EveryoneのActiveDirectoryアクセス規則オブジェクト生成
ActiveDirectoryAccessRule allowEveryone = new ActiveDirectoryAccessRule(everyoneSid, ActiveDirectoryRights.ExtendedRight, AccessControlType.Allow, changePasswordGuid);
ActiveDirectoryAccessRule denyEveryone = new ActiveDirectoryAccessRule(everyoneSid, ActiveDirectoryRights.ExtendedRight, AccessControlType.Deny, changePasswordGuid);
//NT AUTHORITY\SELFのActiveDirectoryアクセス規則オブジェクト生成
ActiveDirectoryAccessRule allowSelf = new ActiveDirectoryAccessRule(selfSid, ActiveDirectoryRights.ExtendedRight, AccessControlType.Allow, changePasswordGuid);
ActiveDirectoryAccessRule denySelf = new ActiveDirectoryAccessRule(selfSid,ActiveDirectoryRights.ExtendedRight, AccessControlType.Deny, changePasswordGuid);
//ユーザアカウントオブジェクトのセキュリティ制御オブジェクト生成
ActiveDirectorySecurity ads = dEntUsr.ObjectSecurity;
//ユーザアカウントオブジェクトのアクセス規則のコレクションを取得
AuthorizationRuleCollection accessRules = ads.GetAccessRules(true, false, typeof(NTAccount));
//LINQでパスワード許可拒否権利のある AB721A53-1E2F-11D0-9819-00AA0040529B に一致するルールを取得
var query = from rule in accessRules.OfType
() where rule.ObjectType == changePasswordGuid
select rule;
foreach (ActiveDirectoryAccessRule rule in query)
{
bool modified = false;
if (rule.IdentityReference.Value == @"NT AUTHORITY\SELF")
{
if (allowChangePassword && rule.AccessControlType == AccessControlType.Deny)
{
//パスワード変更許可にする
ads.ModifyAccessRule(AccessControlModification.Reset, allowSelf, out modified);
}
else if (!allowChangePassword && rule.AccessControlType == AccessControlType.Allow)
{
//パスワード変更拒否にする
ads.ModifyAccessRule(AccessControlModification.Reset, denySelf, out modified);
}
}
else if (rule.IdentityReference.Value == @"Everyone")
{
if (allowChangePassword && rule.AccessControlType == AccessControlType.Deny)
{
//パスワード変更許可にする
ads.ModifyAccessRule(AccessControlModification.Reset, allowEveryone, out modified);
}
else if (!allowChangePassword && rule.AccessControlType == AccessControlType.Allow)
{
//パスワード変更拒否にする
ads.ModifyAccessRule(AccessControlModification.Reset, denyEveryone, out modified);
}
}
}
//設定を保存
dEntUsr.CommitChanges();
}
パスはDirectoryEntryで取得したUserオブジェクトの distinguishedName(識別名 DN,OU,DC,JP)が使えるようです。
また、上記ソースで出てくる GUID:"AB721A53-1E2F-11D0-9819-00AA0040529B" というのは@IT:セキュリティ設定を記述するSDDL文字列とは?によると、User-Change-Password という名前で、パスワードの変更権利を意味するらしいですね。