『【IDM】パスワード同期機能の有効活用 その3 ~ unixUserPassword 属性から暗号化されたパスワードを取得する』PowerShell 編
同僚の安納さんのブログで、Active Directory と Unix/Linux のパスワードの同期機能について、Windows Server 2008 での方法が詳しく書かれています。
私も大変興味のある分野ですので、さっそく試してみました。ブログに書かれている通りに進めていくと、簡単にセットアップできました。ID の統合を検討されている方は、この同期の手法は、 Linux/Unix のログイン認証を AD に統合するよりも、わかりやすくシンプルなので、まずはここから始めてみるのもいいかもしれませんね。
ところで、その3では Linux/Unix に同期される、暗号化されたパスワード文字列を、LDAP クエリーで取り出す方法が紹介されていますが、ここでは PowerShell 版を作ってみたいと思います。以下のようなパスワード文字列を取り出します。
まずは、Active Directory に LDAP で接続し、クエリの準備をします。
$domain = [adsi]""
$searcher = New-Object System.DirectoryServices.DirectorySearcher $domain
$searcher.Filter = '(&(objectClass=User)(sAMAccountName=testuser001))'
カレントの ADSI オブジェクトを取得し ($domain)、検索のための DirectorySearcher オブジェクト を作成します ($searcher)。$searcher にフィルタを設定します。LDAP サーバーや、バインドするオブジェクトを指定する場合は、パスを指定してください。
$domain = [adsi]"LDAP://localhost/dc=example1,dc=jp"
$domain の中を見てみると、ディレクトリに関する情報が入っています。(以下、確認のための操作には、プロンプト PS C:\> を付けています。)
PS C:\> $domain | format-list *
objectClass : {top, domain, domainDNS}
distinguishedName : {DC=example1,DC=jp}
instanceType : {5}
...(略)...
次に LDAP クエリを実行し、ユーザーオブジェクトを取得します。
$user = $searcher.FindOne()
$user の Properties プロパティに属性が入っていますので unixUserPassword の値を確認してみましょう。(DirectorySearcher の PropertiesToLoad プロパティに指定がない場合は、すべての属性が Properties に返されます。) unixUserPassword は複数値ですので、最初の値を取り出すため [0] を指定します。
PS C:\> $user.Properties.unixuserpassword[0]
71
121
49
110
65
77
90
105
65
88
84
102
89
PS C:\> $user.Properties.unixuserpassword[0] | Get-Member
TypeName: System.Byte[]
...(略)...
バイト列になっていますので、これを文字列に変換します。変換には、.NET Framework の System.Text のクラスが便利です。
$enc = new-object System.Text.UTF8Encoding
$password = $enc.GetString($user.Properties.unixuserpassword[0])
このようにしてパスワード文字列を取り出すことができます。
PS C:\> $password
Gy1nAMZiAXTfY