Samba+OpenLDAPによるドメインログオン環境 を書くために、いろいろと調べた時の途中経過のようなものです。確認した環境は samba-3.4.5 on Cent OS 5.4 です。このため、記述内容も Cent OS 5.x や RPM パッケージの作法に依存したものになっています。 他の Linux ディストリビューションや他の OS をお使いの方は、逐次読み替えてください。
secrets.tdb
Samba が正しく動作するためには、Samba が管理者権限(*2)で LDAP にアクセスできることが必要である。
このために、Samba は前もって LDAP の管理者パスワード(*3)を知っておかなければならない。
LDAP の管理者パスワードは smb.conf
で指定するのではなく、/etc/samba/secrets.tdb
に格納される。
Samba の RPM パッケージインストールの直後には、このファイルは存在しない。
/etc/samba/smb.conf
の ldap admin dn
ディレクティブで指定する。/etc/openldap/slapd.conf
の rootpw
ディレクティブで指定する。LDAP にアクセスするためのパスワードの設定
secrets.tdb
の作成および管理者パスワードの保存には、Samba を起動する前に以下のコマンドを投入する。
# smbpasswd -w LDAPの管理者パスワード Setting stored password for "cn=admin,dc=example,dc=com" in secrets.tdb
secrets.tdb
には何が入っているか?
以下のコマンドで確かめることができる:
root@celsior:~# tdbdump /etc/samba/secrets.tdb { key(50) = "SECRETS/LDAP_BIND_PW/cn=admin,dc=example,dc=com" data(8) = "naisho\00" }
いわゆるキー・バリュー形式で格納されていることがわかる。
という実験をしてみた。LDAP 認証(pam_ldap)が有効なまま LDAP を止めるとあらゆる認証処理が重くなって動作に支障を及ぼすので、まず LDAP 認証を止めてから LDAP を止める。
root@celsior:~# authconfig --disableldap --disableldapauth --update nscd を停止中: [ OK ] nscd を起動中: [ OK ] root@celsior:~# service ldap stop slapd を停止中: [ OK ]
その後 samba を起動する。前述の secret.tdb も消しておく。
root@celsior:~# rm -f /etc/samba/secrets.tdb root@celsior:~# service smb start SMB サービスを起動中: [ OK ] NMB サービスを起動中: [ OK ] root@celsior:~# ps ax|grep mb|grep -v grep 7151 ? Ss 0:00 smbd -D 7154 ? Ss 0:00 nmbd -D
この場合でも Samba は起動だけはするようだ(以前はエラーになっていたような気もする)。
内部的に、どういう状態になっているか見てみる。
root@celsior:~# tail -7 /var/log/samba/log.nmbd ***** [2010/01/08 16:22:11, 0] nmbd/nmbd_become_lmb.c:395(become_local_master_stage2) ***** Samba name server CELSIOR is now a local master browser for workgroup MYDOMAIN on subnet 192.168.40.101 *****
nmbd の動作的には、特に支障はないらしい。
secrets.tdb については、存在しなければ自動的に作られるようだ。
root@celsior:/etc/samba# tdbdump secrets.tdb { key(23) = "SECRETS/SID/MYDOMAIN" data(68) = "\01\04\00\00\00\00\00\05\15\00\00\00\D18\F8\D70\E3 w;\5CG%\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" } { key(19) = "SECRETS/SID/CELSIOR" data(68) = "\01\04\00\00\00\00\00\05\15\00\00\00\D18\F8\D70\E3 w;\5CG%\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }
SECRETS/SID/MYDOMAIN
と SECRETS/SID/CELSIOR
という2つのエントリが作成されている。data
部分は全く同じのようだ。
smbd 的にはどうだろう?
root@celsior:/var/log/samba# tail -6 smbd.log [2010/01/08 16:24:20, 0] passdb/secrets.c:914(fetch_ldap_pw) fetch_ldap_pw: neither ldap secret retrieved! [2010/01/08 16:24:20, 0] lib/smbldap.c:1012(smbldap_connect_system) ldap_connect_system: Failed to retrieve password from secrets.tdb [2010/01/08 16:24:20, 0] smbd/server.c:1197(main) ERROR: failed to setup guest info.
LDAP の管理者パスワードを取得するために何度がリトライを繰り返した後、あきらめている。
Samba (というか Windows ネットワーク)では、各ネットワークノードを SID(Security ID)という識別子で管理している。Samba サーバが Windows ネットワークに参加するためには、事前に自分自身の SID (localsid) を決めておかなければならない。これは net setlocalsid
コマンドで指定する。設定済みの自(Samba) SID の表示は net getlocalsid
コマンドで行う。
ここで、OpenLDAP が未起動、secrets.tdb もなし(≒ LDAP 管理者パスワードが未設定)、かつ Samba も未起動状態で net getlocalsid
をやってみると、以下のようになった。
root@celsior:~# service ldap status slapd は停止しています root@celsior:~# service smb stop SMB サービスを停止中: [失敗] NMB サービスを停止中: [ OK ] root@celsior:~# rm -f /etc/samba/secrets.tdb root@celsior:~# net getlocalsid [2010/01/08 16:39:16, 0] passdb/secrets.c:914(fetch_ldap_pw) fetch_ldap_pw: neither ldap secret retrieved! [2010/01/08 16:39:16, 0] lib/smbldap.c:1012(smbldap_connect_system) ldap_connect_system: Failed to retrieve password from secrets.tdb
LDAP 管理者パスワードを取得しようとしてリトライしている。ただし、この状態でも secrets.tdb は自動作成されている。中身はカラのようだ。
root@celsior:~# tdbdump /etc/samba/secrets.tdb
LDAP 管理者パスワードが設定されている場合は以下のような挙動が見られた。
root@celsior:# smbpasswd -w rootpwd Setting stored password for "cn=admin,dc=example,dc=com" in secrets.tdb root@celsior:~# tdbdump /etc/samba/secrets.tdb { key(50) = "SECRETS/LDAP_BIND_PW/cn=admin,dc=example,dc=com" data(7) = "rootpwd\00" } root@celsior:~# net getlocalsid [2010/01/08 16:42:56, 0] lib/smbldap.c:1052(smbldap_connect_system) failed to bind to server ldap://localhost with dn="cn=admin,dc=example,dc=com" Error: Can't contact LDAP server (unknown)
正しく(?)、OpenLDAP サーバーにアクセスに行こうとしている。
次は、LDAP を動かしてからやってみる。ドメイン情報は SambaDomainName オブジェクトとして登録されるが、当初は何もないことを確認しておく。Samba のプロセスもまだ動いていない。
root@celsior:~# service smb status smbd は停止しています nmbd は停止しています root@celsior:~# service ldap start slapd の設定ファイルをチェック中: config file testing succeeded [ OK ] slapd を起動中: [ OK ] m-hotta@celsior:~$ ldapsearch -x -LLL '(sambadomainname=*)' root@celsior:~# tdbdump /etc/samba/secrets.tdb { key(50) = "SECRETS/LDAP_BIND_PW/cn=admin,dc=example,dc=com" data(7) = "rootpwd\00" } root@celsior:~# net getlocalsid SID for domain CELSIOR is: S-1-5-21-150273636-2295251027-4190084592
CELSIOR は Samba が動作しているマシンのホスト名で、デフォルトではこれがコンピュータ名となる。net getlocalsid
を実行するためには LDAP が動いていないといけないが、Samba が動いている必要はなさそうである。
ところで、前述の CELSIOR の SID はどこから持ってきたのだろうか?
root@celsior:~# tdbdump /etc/samba/secrets.tdb { key(50) = "SECRETS/LDAP_BIND_PW/cn=admin,dc=example,dc=com" data(8) = "naisho\00" } { key(19) = "SECRETS/SID/CELSIOR" data(68) = "\01\04\00\00\00\00\00\05\15\00\00\00\08\10\98`\BEX\FB\15\B2QU\E3\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" } { key(15) = "SECRETS/SID/MYDOMAIN" data(68) = "\01\04\00\00\00\00\00\05\15\00\00\00\08\10\98`\BEX\FB\15\B2QU\E3\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }
net getlocalsid
の実行後、/etc/samba/secrets.tdb
に SECRETS/SID/MYDOMAIN
エントリが追加されていた。data
の部分は SECRETS/SID/MYDOMAIN
のものと全く同じになっているようだ。
次に、LDAP の内容を見てみよう。
m-hotta@celsior:~$ ldapsearch -x -LLL '(sambadomainname=*)' dn: sambaDomainName=MYDOMAIN,dc=example,dc=com sambaDomainName: MYDOMAIN sambaSID: S-1-5-21-150273636-2295251027-4190084592 sambaAlgorithmicRidBase: 1000 objectClass: sambaDomain sambaNextUserRid: 1000 sambaMinPwdLength: 5 sambaPwdHistoryLength: 0 sambaLogonToChgPwd: 0 sambaMaxPwdAge: -1 sambaMinPwdAge: 0 sambaLockoutDuration: 30 sambaLockoutObservationWindow: 30 sambaLockoutThreshold: 0 sambaForceLogoff: -1 sambaRefuseMachinePwdChange: 0
この時点で sambaDomainName=MYDOMAIN オブジェクトが暗黙のうちに LDAP のトップレベルツリー(*4)直下に自動的に作成されていた。MYDOMAIN は smb.conf
の workgroup
ディレクティブで指定していたドメイン/ワークグループ名である。このオブジェクトで使われている属性はsamba.schema に収録されている属性値で規定されている。
smb.conf
の ldap suffix
ディレクトリで指定するCELCIOR の SID として表示された値は、実は MYDOMAIN エントリの sambaSID そのもののようである。*get*localsid といいながら、なければ set 、という動作をするようである。
なお参考までに net getlocalsid
を一般ユーザー権限で動かしてみると、以下のようなエラーになった。
m-hotta@celsior:~$ net getlocalsid [2009/12/22 09:15:18, 0] passdb/secrets.c:71(secrets_init) Failed to open /etc/samba/secrets.tdb
これは、一般ユーザーからは /etc/samba/secrets.tdb
に対するアクセス権がないため、LDAP の管理者パスワードが取得できないことを示している。
SambaSID は S-1-5-21-(数字1)-(数字2)-(数字3)[-(数字4)] のような構造になっている。SID の構造は Windows で規定されており、S-1-5-21 はドメインに関する SID であることを表している。先頭の数文字についてはWindows で規定されているセキュリティ識別子(SID)を参照されたい。
数字1 ~ 数字3 はドメイン識別子であり、sambaDomainName エントリの生成時に動的に生成される。これらの数値は、同じドメイン内に定義されているすべてのオブジェクト(ユーザ、グループなど)で同一になる。
sambaDomainName エントリの sambaSID は 数字3 までしかないが、ユーザやグループのエントリの場合は 数字4 まである。数字4 の部分は /etc/passwd
や /etc/group
で現れる UID/GID と似たような考え方であり、ひとつのドメイン内でオブジェクトを識別するための相対識別子(RID)である。
なお、今回の手順は新規に PDC を作る(ドメイン SID の生成)時のものである。既存のドメインに BDC やワークグループサーバーを追加する場合は、各 Samba ホストで net setlocalsid
を行う。この際、所属したいドメインの SambaSID を指定すればよい。
slapd.conf
でdatabase config
を使う場合、Provider / Consumer に関わらず、いったん LDAP DB が構築された後は、OpenLDAP サーバ再起動時に slapd.conf
の中身は評価されないようである。ただし設定ファイルの存在チェックだけは行われるので、わかりやすいように slapd.conf
は空ファイルに置き換えておくとよい。LDAP の設定変更をする場合は、ADS(Apache Directory Studio)などで当該 LDAP サーバーの cn=config
ツリーに接続(*1)し、GUI ツールで行う。
slapd.conf
の secret
ディレクティブで指定されたものを使用するここまで確認できたので、Samba を起動してみる。
root@celsior:~# service smb start SMB サービスを起動中: [ OK ] NMB サービスを起動中: [ OK ]
Samba のログファイルとしては、log.nmbd と log.smbd が作られる。log.nmbd の主な内容は以下の通り:
become_domain_master_browser_wins: querying WINS server from IP 192.168.40.101 for domain master browser name MYDOMAIN<1b> on workgroup MYDOMAIN become_logon_server_success: Samba is now a logon server for workgroup MYDOMAIN on subnet 192.168.40.101 become_logon_server_success: Samba is now a logon server for workgroup MYDOMAIN on subnet UNICAST_SUBNET Samba server CELSIOR is now a domain master browser for workgroup MYDOMAIN on subnet UNICAST_SUBNET Samba server CELSIOR is now a domain master browser for workgroup MYDOMAIN on subnet 192.168.40.101 Samba name server CELSIOR is now a local master browser for workgroup MYDOMAIN on subnet 192.168.40.101
domain master browser(DMB)とかlocal master browser(LMB)などという単語が見える。これらの用語についてはMicrosoft ネットワークを解剖する 第3回「ブラウジング機能」あたりを参照してほしい。
この時点で WINS に登録された内容は以下のようになった。なお WINDOWS7 はテスト用の Windows7 端末である。
root@celsior:~# cat /var/lib/samba/wins.dat VERSION 1 0 "CELSIOR#03" 1263540750 192.168.40.101 66R "CELSIOR#20" 1263540750 192.168.40.101 66R "WINDOWS7#20" 1263581631 192.168.40.50 64R "MYDOMAIN#1b" 1263540750 192.168.40.101 64R "WORKGROUP#00" 1263581631 0.0.0.0 e4R "MYDOMAIN#1c" 1263540750 192.168.40.101 e4R "CELSIOR#00" 1263540750 192.168.40.101 66R "WINDOWS7#00" 1263581631 192.168.40.50 64R "MYDOMAIN#00" 1263540750 0.0.0.0 e4R "MYDOMAIN#1e" 1263540750 0.0.0.0 e4R
各エントリ名には、必ず #XX としてノード属性(NetBIOS サフィックス)が付いている。詳細は後述する。
wins.dat
ファイルがあるディレクトリには多数の *.tdb ファイルが作られていた。これらの中身も tdbdump
コマンドで見れるので、興味のある方は参照してほしい。
Windows ネットワーク上ではコンピュータ名でノードを識別するが、これは正確には NetBIOS 名と呼ばれる。NetBIOS 名は 15 文字までに制限されており、16 文字目に属性を表す 1 バイトが付加される。これを NetBIOS サフィックスと呼ぶ。代表的なものを以下に示す。
名前 | 値(16進数) | 種類 | 意味 |
---|---|---|---|
<computername> | 00 | U | ワークステーション サービス |
<\\--__MSBROWSE__> | 01 | G | マスタ ブラウザ |
<computername> | 20 | U | ファイル サーバー サービス |
<domain> | 00 | G | ドメイン名 |
<domain> | 1B | U | ドメイン マスタ ブラウザ |
<domain> | 1C | G | ドメイン コントローラ |
<domain> | 1D | U | マスタ ブラウザ |
<domain> | 1E | G | ブラウザ サービスの選択 |
NetBIOS 名の種類(マイクロソフトのサポート情報より転載)
詳細については NetBIOS サフィックス (NetBIOS 名の 16 番目の文字)を参照のこと。
この図に従って WINS.DAT の中身を見てみると、ドメイン コントローラは "MYDOMAIN#1c" であり、その IP アドレス 192.168.40.101 は CELSIOR のものであることがわかる。