SSブログ

Active DirectoryドメインのNetBIOSドメイン名を問い合わせる方法 [ソフトウェア/PC関係]

久々のブログ更新で,全く唐突にActive Directoryの話題。

本業の方で必要になって,ちょっと調べてみたことをご紹介。Active Directory(AD)のドメイン名は,"example.local"みたいな,Internetのドメイン名と同じ形式をしている。一方で,従来のWindowsのドメイン名(NetBIOSで使われているもの)も依然として存在している。ドメイン内のPCに,ドメイン・ユーザーとしてログインする時は,「NetBIOSドメイン名\ユーザー名」を指定するが,これはAD環境でもまだ有効だ。デフォルトでは,ADドメイン名の最初のピリオドまでの部分が,NetBIOSドメイン名として使われるのだが,別のものに設定することも可能だ。そのため,ADドメイン名からNetBIOSドメイン名を機械的に得ることはできないことになる。ではどうすれば良いか,というのが今回のお題。

そもそもなんでそんなことを調べ始めたかという経緯を説明しておこう。ADサーバーというのはLDAPサーバーでもある。なのでLDAPプロトコルを利用して,ユーザー情報などを問い合わせることができる。しかし,そのためにはまず,LDAPサーバーがどれなのか知る必要がある。通常の構成では,DNSがこれを知っているはずで,例えばLinuxからだと,ターミナルで

dig +short SRV _ldap._tcp.<ADドメイン名>

というコマンドを実行すれば良い。例えば,example.localドメインに対しては,

# dig +short SRV _ldap._tcp.example.local
0 100 389 ads.example.local

のような形で,ホスト名を返してくれる。3番めの数字はポート番号。このホスト名とポート番号を使って,LDAPプロトコルで問い合わせをすれば良い。

例えば,"Suzuki"という名字のユーザーを全て検索してみよう。ここではPythonを使ったサンプル・コードを示す。Pytho-LDAPという追加パッケージを使って,

import ldap
con = ldap.open('ads.example.local')
con.simple_bind_s()

base_dn = 'cn=Users,dc=example,dc=local';
filters = '(sn=Suzuki)'
res = con.search_s(base_dn, ldap.SCOPE_SUBTREE, filters)

for r in res:
	attrs = r[1]
	for k in attrs.keys():
		print "%s: %s" % (k, attrs[k])
	print '----------------------------'

のように書ける(エラー処理等は省略)。実行すれば,該当するユーザーに設定されている全属性が,一人分ずつ表示される。その中で,ADユーザー名は,userPrincipalNameという属性の値として返される。これは"suzuki@example.local"のように,ADドメイン名が付加された形になっている。一方で,NetBIOSユーザー名は,"sAMAccountName"という属性になる。"suzuki"のような形式だ。こちらにはNetBIOSドメイン名がついていない。他の属性にも,NetBIOSドメイン名の情報は含まれない。では,先程のような,「NetBIOSドメイン名\ユーザー名」という形式を得るにはどうすれば良いのだろう。という訳である。

ADサーバーに登録されているユーザーのドメインは,当然ADサーバーのドメインと同じはず。なので,ADサーバーのNetBIOSドメイン名を知る方法があればよい。ADサーバーにログインして,「Active Directory ユーザーとコンピューター」で調べれば分かることだが,ここではあくまで,プログラムを使って問い合わせたい。LDAPで問い合わせることができれば,なお良い。

なかなか苦戦したのだが,散々Webで検索した結果,ようやく正解らしきものにたどり着いた。LDAPの「cn=Partitions,cn=Configuration,dc=example,dc=local」のノードの下に,「cn=<NetBIOSドメイン名>,cn=Partitions,cn=Configuration,dc=example,dc=local」というノードがあるというのである。って,そのNetBIOSドメイン名を知りたいんじゃないのか? と思うかもしれないが,心配はない。そのノードは「nETBIOSName」という属性を持っていて,それがまさにNetBIOSドメイン名だということだ。つまり,その属性を持つノードを検索すれば良い。例えば,次のようなPythonコードになる。

import ldap
con = ldap.open('ads.example.local')
con.simple_bind_s()

base_dn = 'cn=Partitions,cn=Configuration,dc=example,dc=local';
filters = '(nETBIOSName=*)'
attrs = ['nETBIOSName']
res = con.search_s(base_dn, ldap.SCOPE_ONELEVEL, filters, attrs)
print res[0][1]['nETBIOSName'][0]

という訳で,取り敢えず解決。より複雑な構成の場合には,dnsRoot属性が所望のADドメイン名であることもチェックした方が良いのかもしれないが,環境がないので未確認である。悪しからず。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。