samba.tips

Samba+OpenLDAPによるドメインログオン環境 を書くために、いろいろと調べた時の途中経過のようなものです。確認した環境は samba-3.4.5 on Cent OS 5.4 です。このため、記述内容も Cent OS 5.x や RPM パッケージの作法に依存したものになっています。 他の Linux ディストリビューションや他の OS をお使いの方は、逐次読み替えてください。


  1. secrets.tdb

    1. Samba が正しく動作するためには、Samba が管理者権限(*2)で LDAP にアクセスできることが必要である。
      このために、Samba は前もって LDAP の管理者パスワード(*3)を知っておかなければならない。

    2. LDAP の管理者パスワードは smb.conf で指定するのではなく、/etc/samba/secrets.tdb に格納される。
      Samba の RPM パッケージインストールの直後には、このファイルは存在しない。

      • (*2)… /etc/samba/smb.confldap admin dn ディレクティブで指定する。
      • (*3)… /etc/openldap/slapd.confrootpw ディレクティブで指定する。
    3. LDAP にアクセスするためのパスワードの設定

      secrets.tdb の作成および管理者パスワードの保存には、Samba を起動する前に以下のコマンドを投入する。

      # smbpasswd -w LDAPの管理者パスワード
      Setting stored password for "cn=admin,dc=example,dc=com" in secrets.tdb
      
    4. 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"
      }
      

      いわゆるキー・バリュー形式で格納されていることがわかる。

  2. (Open)LDAP が動いていない場合、どうなるか?

    という実験をしてみた。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/MYDOMAINSECRETS/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 の管理者パスワードを取得するために何度がリトライを繰り返した後、あきらめている。

  3. localsid はどこ?

    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 サーバーにアクセスに行こうとしている。

  4. localsid の自動設定

    次は、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 が動いている必要はなさそうである。

  5. sambaDomainName エントリ

    ところで、前述の 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.tdbSECRETS/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.confworkgroup ディレクティブで指定していたドメイン/ワークグループ名である。このオブジェクトで使われている属性はsamba.schema に収録されている属性値で規定されている。

    • (*4)… smb.confldap 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 の管理者パスワードが取得できないことを示している。

  6. SID の構造

    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 を指定すればよい。

  7. slapd.conf の扱い

    slapd.confdatabase configを使う場合、Provider / Consumer に関わらず、いったん LDAP DB が構築された後は、OpenLDAP サーバ再起動時に slapd.conf の中身は評価されないようである。ただし設定ファイルの存在チェックだけは行われるので、わかりやすいように slapd.conf は空ファイルに置き換えておくとよい。LDAP の設定変更をする場合は、ADS(Apache Directory Studio)などで当該 LDAP サーバーの cn=config ツリーに接続(*1)し、GUI ツールで行う。

    • (*1)… パスワードは slapd.confsecret ディレクティブで指定されたものを使用する
  8. Samba を起動する

    ここまで確認できたので、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 コマンドで見れるので、興味のある方は参照してほしい。

  9. NetBIOS サフィックス

    Windows ネットワーク上ではコンピュータ名でノードを識別するが、これは正確には NetBIOS 名と呼ばれる。NetBIOS 名は 15 文字までに制限されており、16 文字目に属性を表す 1 バイトが付加される。これを NetBIOS サフィックスと呼ぶ。代表的なものを以下に示す。

    代表的な 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 名の種類(マイクロソフトのサポート情報より転載)

    一意(U)
    名前に対して、対応する IP アドレスが 1 つだけ存在することができます。ネットワークでは、複数のデバイスが同じ名前で登録されている場合があります。そのような場合でも、サフィックスが異なることで名前の一意性が保たれます。
    グループ (G)
    通常のグループです。同じ名前に対して、対応する IP アドレスが複数存在することができます。WINS は、グループ名の名前照会に対して、限定されたブロードキャスト アドレス (255.255.255.255) で応答を返します。これらのアドレスに対する転送はルーターでブロックされるため、サブネット間の通信を実現するためにインターネット グループが設計されました。

    詳細については NetBIOS サフィックス (NetBIOS 名の 16 番目の文字)を参照のこと。

    この図に従って WINS.DAT の中身を見てみると、ドメイン コントローラは "MYDOMAIN#1c" であり、その IP アドレス 192.168.40.101 は CELSIOR のものであることがわかる。

関連情報

up