(.Net,ADSI)識別名(DN)のエスケープ
ActiveDirectoryというかLDAPの仕様だと思うんですが、重複した識別名(DN)のオブジェクトは作成できません。
で、.Netから新規ActiveDirectoryユーザを作成するツールを作ったんですが、DNの重複チェックができていませんでした。(ログインアカウント名の重複チェックはできてたんですけどね。。)
それで、新規作成するユーザ名からDNを生成して、それがActiveDirectoryに存在するかどうかのチェックをすることにしました。
単純にユーザ名、OU名、ドメイン名からDNを生成して、生成されたDNが既にあるかどうかをチェックすればいいだけなんですが、どうやらDNにはエスケープすべき特殊文字があるようです。
それは、「#」、「,」、「+」、「"」、「\」、「<」、「>」、「;」のようです。
ということで、ユーザ名を¥でエスケープしてActiveDirectoryから検索するコードを書いてみました。(C#)
(既にOU名とドメイン名は分かってることとします。)
string username = "hoge#<> ,hoge+";
string ou = "OU=testou";
string domain ="DC=hogedomain,DC=jp";
//識別名(DN)を作るにあたって「#」、「,」、「+」、「"」、「\」、「<」、「>」、「;」はエスケープ
string strDN = return System.Text.RegularExpressions.Regex.Replace(username, "#|,|\\+|\"|\\|<|>|;", "\\$&");
//DN名生成
strDN = "CN=" + strDN + "," + ou + "," + domain;
DirectoryEntry mDrctEntry;
mDrctEntry = new DirectoryEntry(@"LDAP://domaincontroler/DC=hogedomain,DC=jp", "administrator", "Passwd");
// LDAP検索オブジェクトを作成
DirectorySearcher drSearch = new DirectorySearcher(mDrctEntry);
// アカウントフィルターを設定 識別名で検索
drSearch.Filter = "(distinguishedName=" + strDN + ")";
// 検索する
SearchResultCollection scn = drSearch.FindAll();
//見つからなければnullを返す。
if (scn == null || scn.Count <= 0){
//見つからなかった時の処理
}else{
//見つかった時の処理
}
特殊文字をエスケープする部分は正規表現を使って置換しています。
正規表現での置換は、Text.RegularExpressions.Regex クラスの Replace メソッドを使えばいいようです。
置換する文字列に $& を指定すると、パターンで引っ掛かった文字を使うことができるようです。
久しぶりに正規表現つかましたが、しょっちゅう触ってないと難しいですね。
もしかしたら、エスケープしてくれるようなメソッドがあるのかもしれませんが、見当たらなかったので今回は手で書きました。
参考: