S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

DirectoryEntryを使ってADのユーザー情報にアクセスする

System.DirectoryServices.DirectoryEntryクラスを使って(LDAPで)ADのユーザー情報にアクセスする時の引数の指定が判らなかったのでメモ。
VB.NETで確認したけど、下記のような感じでユーザー情報が取得できた。

Dim user As DirectoryEntry = 
    New DirectoryEntry(
        "LDAP://ドメイン名/CN=取得するユーザー名,CN=Users,DC=aaa,DC=bbb,DC=ccc",
         Nothing,
         Nothing,
         AuthenticationTypes.Secure
        )


DirectoryEntry コンストラクター (String, String, String, AuthenticationTypes)

path

LDAP://ADサーバ名 or IPアドレス/CN=取得するユーザー名,CN=Users,DC=aaa,DC=bbb,DC=ccc

ハマったのが、「CN=Users」を指定しないと下記のような例外が発生して取得できない。

System.DirectoryServices.DirectoryServicesCOMException (0x80072030): サーバーにそのようなオブジェクトはありません。

他の所属グループを指定してもダメで、Usersを指定しないと取得できない。
Usersを指定しないと取得できない理由は不明。
(2014-08-27追記)
Usersは所属するグループではなく、ADのフォルダのUsersを指定している。
ビルトイングループの場合は、「CN=Builtin」を指定すればアクセスできる。


DirectoryServiceを使用してディレクトリオブジェクトにバインドするに、接続文字列にドメイン名が指定できるとの記載があったので、下記でも取得できることを確認した。

LDAP://ドメイン名/CN=取得するユーザー名,CN=Users,DC=aaa,DC=bbb,DC=ccc

usernameとpassword

これ指定しなくても(null/nothing)取得できるけど、なんかセキュリティ的に納得できんのじゃけど。
現時点でVisualStudioでデバッグしょーるだけなんで、そのログインユーザーで認証してるんだろうか?
下記のAuthenticationTypeと関係あるのか?

authenticationType

AuthenticationTypes.Secureを指定。

からのADのユーザーのパスワードを変更

Dim user As DirectoryEntry = 
    New DirectoryEntry(
        "LDAP://ドメイン名/CN=取得するユーザー名,CN=Users,DC=aaa,DC=bbb,DC=ccc",
         Nothing,
         Nothing,
         AuthenticationTypes.Secure
        )
user.Invoke("SetPassword", oldpasswd)
user.Invoke("ChangePassword", oldpasswd, newpasswd)

さすがにクライアントPCからだと"SetPassword"で下記のような例外が発生するが、ADサーバで実行するとすんなり変更できた。

System.UnauthorizedAccessException: アクセスが拒否されました。 (HRESULT からの例外: 0x80070005 (E_ACCESSDENIED))

これをIISで動かしてWebアプリでパスワード変更とかできれば…