[Chapter 3] 3.3 SMB/CIFS への手引き
Date: 1999-11-05T21:31:30Z

| ## Using Samba Robert Eckstein, David Collier-Brown, Peter Kelly 共著 第一版 1999 年 11 月 1-56592-449-5, 注文番号: 4495 416 ページ, 34.95 ドル ハードコピー版(英語)を購入する 目次

| Chapter 3 Windows クライアントの設定 |

> ## 3.3 SMB/CIFS への手引き

> この章では SMB/CIFS を簡単に解説する。SMB/CIFS は、Windows 95/98/NT マシンが Samba 等と通信する際に用いるプロトコルである。高レイヤの SMB プロトコルは比較的単純である。SMB プロトコルはローカルのディスクやプリンタに対して行うようなファイルやプリンタに対する全ての操作を行うためのコマンドを含んでいる。例えば以下のような操作である:

> - ファイルのオープンとクローズ

> - ファイルとディレクトリの作成と削除

> - ファイルの読み取りと書き込み

> - ファイルの検索

> - 印刷スプールへのファイルのキューイングやデキューイング

> これらの各操作は SMB メッセージにエンコードされ、サーバから送出される。元々 SMB という名称はそのデータフォーマットから来ている。ネットワーク上の他のマシンに伝えるために再設計された標準の DOS システムコールのデータ構造、すなわち Server Message Blocks には幾つかのバージョンがある。

> ### 3.3.1 SMB のフォーマット

> Samba チームの Richard Sharpe は SMB を "リクエスト-レスポンス" プロトコルと定義した。[4] たしかに、クライアントが SMB リクエストをサーバに送ると、サーバは SMB レスポンスをクライアントに返却する。稀にサーバがクライアントに対してレスポンスでないメッセージを送信することもある。

> > [4] Richard の優れた SMB の概要である http://anu.samba.org/cifs/docs/what-is-smb.html を参照のこと

> SMB メッセージは考えている程複雑ではない。メッセージの内部構造について詳しくみていくことにしよう。メッセージは大きく二つの部分に分けることができる。固定サイズの へッダと、メッセージの内容によってサイズが大きく異なる コマンド である。

> #### 3.3.1.1 SMB へッダフォーマット

> 表 3.1 に、SMB へッダのフォーマットを示す。SMB コマンドは SMB へッダの全てのフィールドを必要とするものではない。例えば、クライアントがサーバへの接続を開始する時点では、Tree識別子(Tree identifier) (TID) の値 - これは接続が成功すると付与される - がないため、ヌルの TID (0xFFFF) がへッダ中のフィールドに挿入される。その他のフィールドも 0 でパディングされたり、使われなかったりしているものがある。

> SMB へッダ中のフィールドを 表 3.1に示す。

> 表 3.1: SMB へッダのフィールド
> フィールド | サイズ(バイト) | 記述
> --- | --- | ---
> `0xFF 'SMB'` | `1` | プロトコル識別子
> `COM` | `1` | 0x00 から 0xFF の値をとるコマンドコード
> `RCLS` | `1` | エラークラス
> `REH` | `1` | 予約
> `ERR` | `2` | エラーコード
> `REB` | `1` | 予約
> `RES` | `14` | 予約
> `TID` | `2` | Tree識別子; クライアントがリソースを利用する際に付与されるユニークなID
> `PID` | `2` | 呼び出しプロセスのID
> `UID` | `2` | ユーザ識別子
> `MID` | `2` | 複合識別子(Multiplex identifier); リクエストをプロセス中で振り分ける際に用いられる

> #### 3.3.1.2 SMB コマンドフォーマット

> へッダに続いて、SMB コマンドやリプライを含む可変長のバイト列が続く。Open File (COM フィールドの識別子: `SMBopen`) や Get Print Queue (`SMBsplretq`)のような各コマンドは各々独自のパラメータやデータを持っている。コマンドにも依存するが、SMB へッダフィールドと同様、全てのコマンドフィールドに値が入れられる訳ではない。例えば Get Server Attributes (`SMBdskattr`) コマンドは WCT と BCC フィールドを空に設定する。このコマンドが用いるフィールドの一覧を 表 3.2に示す。

> 表 3.2: SMB コマンドの内容
> フィールド | バイト単位のサイズ | 記述
> --- | --- | ---
> `WCT` | `1` | ワード数
> `VWV` | 可変長 | パラメータのワード (サイズは WCT に記述する)
> `BCC` | `2` | パラメータのバイトカウント
> `DATA` | 可変長 | データ (サイズは BCC によって与えられる)

> これらのフィールドについて理解できないからといって気にしないでほしい。Samba を管理していく上では必要ないことである。ただし、これらを理解すると、システムのメッセージをデバッグするときは便利であろう。 このセクションの後半部では、改良版の tcpdumpを利用して、クライアントとサーバが送信する一般的な SMB メッセージの一部を示そう。(GUI の SMB スニファがよい場合は、GTK ライブラリを利用した "ethereal" を試してみるとよいだろう。このツールについての詳細情報は、Samba のホームページを参照のこと。)

> SMB プロトコルの各コマンドに関する詳細な情報を入手したい時は、ftp://ftp.microsoft.com/developr/drg/CIFS/にある SMB/CIFS のドキュメントを参照のこと

> #### 3.3.1.3 SMB の種類

> SMB プロトコルは制定時より幾度かに亘って、新しいコマンドが拡張されてきた。各々の新しいバージョンは、それまでのバージョンとの下位互換性を有する。これにより、LAN 上に同時に様々な異なったバージョンの SMB プロトコルを実行する多数のクライアントやサーバが存在することとなった。

> 表 3.3 に、SMB プロトコルの主要バージョンについて概要を示した。各々の SMB の亜種には主要なOSのあるリリースのみでサポートされるコマンドを含んだ多数のサブバージョンが存在する。ID 文字列は、クライアントとサーバが互いにどのレベルのプロトコルで通信を行うかを決定する際に用いられる。

> 表 3.3: SMB プロトコルの Dialects
> プロトコル名 | ID 文字列 | 使用OS
> --- | --- | ---
> Core | `PC NETWORK PROGRAM 1.0` |
> Core Plus | `MICROSOFT NETWORKS 1.03` |
> LAN Manager 1.0 | `LANMAN1.0` |
> LAN Manager 2.0 | `LM1.2X002` |
> LAN Manager 2.1 | `LANMAN2.1` |
> NT LAN Manager 1.0 | `NT LM 0.12` | Windows NT 4.0
> Samba's NT LM 0.12 | `Samba` | Samba
> Common Internet File System | `CIFS 1.0` | Windows 2000

> Samba は NT LAN Manager 1.0 の仕様である`NT` `LM` `0.12` を実装している。それは、他の全ての SMB の亜種との下位互換性を保っている。CIFS の仕様は実際のところ LAN Manager 0.12 に幾つかの機能を付加したものである。

> ### 3.3.2 SMB クライアントとサーバ

> 前述したように SMB はクライアント/サーバプロトコルである。厳密にいうと、クライアントがサーバに要求を送信し、サーバは要求を処理してクライアントに返信するという処理になる。しかし、クライアントとサーバの役割は、一つの SMB セッションの中でも、時々逆転する。例えば 図 3.28のように、2台の Windows 95/98 コンピュータが存在するとする。 WIZZIN というコンピュータはネットワークに対してプリンタを共有し、ESCRIME という名前のコンピュータはディスクのディレクトリを公開しているとする。WIZZIN は ESCRIME のネットワークドライブに接続する上では、クライアントの役割を担うが、ESCRIME の印刷をジョブを処理する時はサーバの役割を担う。

> #### 図 3.28: 互いのリソースを共有する2台のコンピュータ

> これは、 Samba の用語において重要な点である:

> - サーバ とは、リソースを公開しているマシンである。

> - クライアント はリソースを利用しようとしているマシンである。

> - サーバは(別のコンピュータのリソースに対する)クライアントとしても機能する。

> サーバに接続されるリソースの容量と、サーバに大容量のディスクや高速なプロセッサがあるかどうかとは全く関係がないことに注意すること。サーバはプリンタが接続された古い 486 マシンかもしれないし、10GB のディスクサービスを行う Ultra SPARC Station かも知れない。

> Microsoft の Windows プロダクトは OS 中に SMB クライアント、サーバ両方の機能を内蔵する。Windows NT 4.0 のユーザは Windows for Workgroups よりも新しいプロトコルを用いることが可能で、それはChapter 6で言及するネットワークセキュリティ的により強固なものを提供する。更に Sun, Compaq, SCO, Hewlett-Packard, Syntax, IBM 等の会社から入手可能な多数の商用 SMB サーバ製品も存在する。不幸なことにクライアント側の製品は殆んど提供されていない。限定的なものとしては DEC の Pathworks プロダクトと、もちろん Samba がある。

> ### 3.3.3 簡単な SMB 通信

> この章を終える前に簡単な SMB の通信をみてみよう。これはいわゆる技術的な情報である - Samba を管理する上では必要ないものである - 従って、好みに応じてここを飛ばしても構わない。この情報を提供する主な目的は、SMB プロトコルがネットワーク上の他のコンピュータとどのようにして接続をネゴシエートするかについての理解を助けることである。

> クライアントとサーバがリソースへの接続を確立するためには、4つのステップがある:

> 1. 仮想接続の確立

> 2. 通信を行うプロトコル種類のネゴシエート

> 3. セッションのパラメータを設定する

> 4. リソースに対する tree connection を確立する

> これらのステップを、前述した有用なツールである tcpdump の修正版を用いて確認しよう。このツールは Samba の Web サイトから入手することが可能である。

> このプログラムは samba.org の samba/ftp/tcpdump-smb ディレクトリからダウンロードすることができる。執筆次点での最新版は 3.4-5 である。このプログラムは普通の tcpdump と同様に利用することができるが、`-s 1500` スイッチにより、先頭部分だけでなく、全てのパケットをキャプチャできるように拡張されている。

> #### 3.3.3.1 仮想接続の確立

> ユーザがネットワークディスクへのアクセスを要求したり、リモートプリンタへの印刷ジョブの送信を開始したりすると、NetBIOS はセッション層での接続を開始する。これにより仮想的な双方向のチャネルがクライアントとサーバとの間に確立される。実際のところ、この接続を確立するのにクライアントとサーバが必要とするのは、たった二つのメッセージだけである。以下の例では、このセッションリクエストとレスポンスを tcpdump でキャプチャしたものを示す:

>     >>> NBT Packet
>     NBT Session Request
>     Flags=0x81000044
>     Destination=ESCRIME      NameType=0x20 (Server)
>     Source=WIZZIN            NameType=0x00 (Workstation)

>     >>> NBT Packet
>     NBT Session Granted
>     Flags=0x82000000

> ### 3.3.4 プロトコル種類のネゴシエート

> この時点で、クライアントとサーバとの間にはチャンネルが開設されている。次にクライアントはサーバに対して SMB プロトコルのネゴシエートを行うメッセージを送信する。前述したように、クライアントは tree identifier (TID) フィールドを空にする。これはまだ利用する TID を取得できていないためである。 tree identifier はサーバ上の共有への接続を識別する数値である。

> メッセージ中のコマンドは `SMBnegprot` である。これはセッションを通じて使われるプロトコルの種類をネゴシエートする要求である。クライアントはサーバに通信可能な全てのプロトコルの種類を送付するが、逆は異なる。

> サーバは `SMBnegprot`リクエストに対して、クライアントが提示した種類のリストに対するインデックスで応答する。 インデックス 0 はリストの最初を示し、0xFF の値は、利用できるプロトコルがないことを示す。この例では、サーバは 5 という値を応答している。これは `NT` `LM` `0.12` dialect がセッションの続きでは利用されることを示す:

>     >>> NBT Packet
>     NBT Session Packet
>     Flags=0x0
>     Length=154

>     SMB PACKET: SMBnegprot (REQUEST)
>     SMB Command   =  0x72
>     Error class   =  0x0
>     Error code    =  0
>     Flags1        =  0x0
>     Flags2        =  0x0
>     Tree ID       =  0
>     Proc ID       =  5371
>     UID           =  0
>     MID           =  385
>     Word Count    =  0
>     Dialect=PC NETWORK PROGRAM 1.0
>     Dialect=MICROSOFT NETWORKS 3.0
>     Dialect=DOS LM1.2X002
>     Dialect=DOS LANMAN2.1
>     Dialect=Windows for Workgroups 3.1a
>     Dialect=NT LM 0.12

>     >>> NBT Packet
>     NBT Session Packet
>     Flags=0x0
>     Length=69

>     SMB PACKET: SMBnegprot (REPLY)
>     SMB Command   =  0x72
>     Error class   =  0x0
>     Error code    =  0
>     Flags1        =  0x0
>     Flags2        =  0x1
>     Tree ID       =  0
>     Proc ID       =  5371
>     UID           =  0
>     MID           =  385
>     Word Count    =  02
>     [000] 05 00

> ### 3.3.5 セッション/ログインパラメータの設定hh

> 次の段階は、セッションで利用するログインパラメータの送信である。これにはアカウント名、パスワード、ワークグループ名、転送できるデータの最大サイズ、ある時点でキューに蓄積できる pending 要求の数を含む。

> 以下の例では、Session Setup コマンドの後ろに別の SMB コマンドが続くことが可能になっている。コマンド名の最後につけられた X の文字がこれを示す。二番目のコマンドの16進のコードは `Com2` フィールドによって与えられる。この例ではコマンドは `0x75`であり、これは Tree Connect and X コマンドを示す。`SMBtconX` メッセージは`smb_buf` バッファ中のリソースの名前を検索する。(これは以下のリクエスト中の最後のフィールドに相当する。) この例において、`smb_buf` には `\\ESCRIME\PUBLIC`という文字列が含まれている。これは ESCRIME 上の共有ディレクトリのフルパス名である。このように "and X" コマンドを利用することで、サーバはクライアントが次のリクエストを送信するのを待つ必要がなくなるため、やとりが高速化する。

> TID はまだ空であることに注意してほしい。セッションが確立され、要求されたリソースに対する接続が行われると、サーバはクライアントに TID を提供する。加えて、パスワードが平文のまま送信されていることにも注意してほしい。これは暗号化パスワードを利用するように変更することが可能である:

>     >>> NBT Packet
>     NBT Session Packet
>     Flags=0x0
>     Length=139

>     SMB PACKET: SMBsesssetupX (REQUEST)
>     SMB Command   =  0x73
>     Error class   =  0x0
>     Error code    =  0
>     Flags1        =  0x10
>     Flags2        =  0x0
>     Tree ID       =  0
>     Proc ID       =  5371
>     UID           =  1
>     MID           =  385
>     Word Count    =  13
>     Com2=0x75
>     Res1=0x0
>     Off2=106
>     MaxBuffer=2920
>     MaxMpx=2
>     VcNumber=0
>     SessionKey=0x1FF2
>     CaseInsensitivePasswordLength=1
>     CaseSensitivePasswordLength=1
>     Res=0x0
>     Capabilities=0x1
>     Pass1&Pass2&Account&Domain&OS&LanMan=
>       KRISTIN PARKSTR Windows 4.0 Windows 4.0
>     PassLen=2
>     Passwd&Path&Device=
>     smb_bcc=22
>     smb_buf[]=\\ESCRIME\PUBLIC

> ### 3.3.6 リソースへの接続の確立

> 最後に、サーバはクライアントに TID を返却する。これにより、ユーザがアクセスを許可され、リソースが利用可能になったことが識別される。更にファイルサービスであることを識別するために、`ServiceType` フィールドを "A" に設定する。利用可能なサービスタイプは以下の通りである:

> - "A" はディスクやファイルを意味する

> - "LPT1" はスプールへの出力を意味する

> - "COMM" は直接接続されたプリンタやモデムを意味する

> - "IPC" は名前つきパイプを意味する

> 出力は以下のようになる:

>     >>> NBT Packet
>     NBT Session Packet
>     Flags=0x0
>     Length=78

>     SMB PACKET: SMBsesssetupX (REPLY)
>     SMB Command   =  0x73
>     Error class   =  0x0
>     Error code    =  0
>     Flags1        =  0x80
>     Flags2        =  0x1
>     Tree ID       =  121
>     Proc ID       =  5371
>     UID           =  1
>     MID           =  385
>     Word Count    =  3
>     Com2=0x75
>     Off2=68
>     Action=0x1
>     [000] Unix Samba 1.9.1
>     [010] PARKSTR

>     SMB PACKET: SMBtconX (REPLY) (CHAINED)
>     smbvwv[]=
>     Com2=0xFF
>     Off2=78
>     smbbuf[]=
>     ServiceType=A:

> これで TID が割り当てられ、クライアントはローカルディスクドライブ上で使えるあらゆるコマンドを、サーバ上のディスクに対しても実行できるようになった。ファイルをオープンしたり、それに読み書きを行ったり、削除したり、新しいファイルを作成したり、ファイル名を作成したりする等の様々なことが行える。

3.2 Windows NT 4.0 コンピュータの設定 |  | 4. ディスク共有

O'Reilly Home | O'Reilly Bookstores | How to Order | O'Reilly Contacts
International | About O'Reilly | Affiliated Companies

© 1999, O'Reilly & Associates, Inc.