3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(.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 メソッドを使えばいいようです。

置換する文字列に $& を指定すると、パターンで引っ掛かった文字を使うことができるようです。

久しぶりに正規表現つかましたが、しょっちゅう触ってないと難しいですね。

もしかしたら、エスケープしてくれるようなメソッドがあるのかもしれませんが、見当たらなかったので今回は手で書きました。

参考:

2.4.4 特殊文字を含むDNの指定

TechNet:オブジェクト名

dobon:正規表現の基本

dobon:正規表現を使って文字列を置換する